- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我有以下代码,并且我不明白为什么在我重新声明get方法时无法访问私有(private)属性。
(function(w,d,a,undefined){
var cfg = {
currency: 'GBP',
exponent: 2
};
var get = function () {
return cfg;
};
a.init = function (settings) {
for (var k in settings) {
cfg[k] = settings[k];
}
};
a.set = function (args) {
get = args.get || get;
//eval(args) //works but why??
};
a.get = function () {
return get();
};
})(window,document,window.fxc = {});
fxc.init({currency: 'EUR'});
// prints, Object { currency="EUR", exponent=2}
console.log(fxc.get());
fxc.set({get: function(msg){
// cannot access private properties
return cfg;
}});
// prints, undefined
console.log(fxc.get());
eval()
,但是肯定不是正确的方法吗?希望有帮助。
最佳答案
没错部分原因是javascript没有私有(private)属性。您正在执行的操作不是声明私有(private)属性(property)。您正在使用一种设计模式,该模式使用闭包来模拟私有(private)属性。
封闭超出了范围。范围是指变量的生命周期,而对象属性是指变量的绑定(bind)。
因此,在讨论闭包之前,让我们简短讨论一下范围。
堆栈:
范围与堆栈框架有关(在计算机科学中,它称为“激活记录”,但大多数熟悉C或汇编语言的开发人员都将其更好地理解为堆栈框架)。范围是堆栈框架,类是对象。我的意思是,如果对象是类的实例,则堆栈框架是作用域的实例。
让我们以编排语言为例。在这种语言中,就像在javascript中一样,函数定义范围。让我们看一个示例代码:
var global_var
function b {
var bb
}
function a {
var aa
b();
}
aa
在
a
函数的作用域内,而变量
bb
在
b
函数的作用域内。请注意,我们不将其称为私有(private)变量。因为私有(private)变量的对立面是公共(public)变量,并且两者都引用绑定(bind)到对象的属性。相反,我们将
aa
和
bb
称为
local variables。局部变量的对立面是全局变量(不是公共(public)变量)。
a
会发生什么:
a()
被调用,创建一个新的堆栈框架。在堆栈上为局部变量分配空间:
The stack:
┌────────┐
│ var aa │ <── a's stack frame
╞════════╡
┆ ┆ <── caller's stack frame
a()
调用
b()
,创建一个新的堆栈框架。在堆栈上为局部变量分配空间:
The stack:
┌────────┐
│ var bb │ <── b's stack frame
╞════════╡
│ var aa │
╞════════╡
┆ ┆
a()
无法访问
b()
中的局部变量,全局范围内的任何其他函数或代码也都无法访问
a()
中的变量。唯一的异常(exception)是全局范围内的变量。从实现的 Angular 来看,这是通过在不属于堆栈的内存区域中分配全局变量来实现的。这通常称为堆。因此,为了完成图片,此时的内存如下所示:
The stack: The heap:
┌────────┐ ┌────────────┐
│ var bb │ │ global_var │
╞════════╡ │ │
│ var aa │ └────────────┘
╞════════╡
┆ ┆
b()
完成并返回,它的堆栈框架已从堆栈中删除:
The stack: The heap:
┌────────┐ ┌────────────┐
│ var aa │ │ global_var │
╞════════╡ │ │
┆ ┆ └────────────┘
a()
完成时,其堆栈框架也会发生同样的情况。这就是如何通过将对象压入和弹出堆栈来自动分配和释放局部变量的方式。
function b {
var bb
return function {
var cc
}
}
function a {
var aa
return b()
}
var c = a()
a()
,依次调用
b()
。创建堆栈框架并将其插入堆栈:
The stack:
┌────────┐
│ var bb │
╞════════╡
│ var aa │
╞════════╡
│ var c │
┆ ┆
b()
返回,因此它的堆栈框架从堆栈中弹出。但是,函数
b()
返回一个匿名函数,该函数捕获闭包中的
bb
。因此,我们弹出堆栈框架,但不要将其从内存中删除(直到对它的所有引用都已被完全垃圾回收):
The stack: somewhere in RAM:
┌────────┐ ┌╶╶╶╶╶╶╶╶╶┐
│ var aa │ ┆ var bb ┆
╞════════╡ └╶╶╶╶╶╶╶╶╶┘
│ var c │
┆ ┆
a()
将函数返回到
c
。因此,对
b()
的调用的堆栈框架链接到变量
c
。请注意,链接的是堆栈框架,而不是范围。这就像从类创建对象一样,是将对象分配给变量,而不是类:
The stack: somewhere in RAM:
┌────────┐ ┌╶╶╶╶╶╶╶╶╶┐
│ var c╶╶├╶╶╶╶╶╶╶╶╶╶╶┆ var bb ┆
╞════════╡ └╶╶╶╶╶╶╶╶╶┘
┆ ┆
c()
,因此变量
cc
尚未分配到内存中的任何位置。在我们调用
c()
之前,它目前只是一个作用域,还不是一个堆栈框架。
c()
时会发生什么?通常,将创建
c()
的堆栈框架。但这一次有所不同:
The stack:
┌────────┬──────────┐
│ var cc var bb │ <──── attached closure
╞════════╤──────────┘
│ var c │
┆ ┆
b()
的堆栈框架附加到
c()
的堆栈框架。因此,从函数
c()
的 Angular 来看,它的堆栈还包含调用
b()
函数时创建的所有变量(再次注意,不是函数b()中的变量而是调用函数b()时创建的变量-在其他情况下换句话说,不是b()的范围,而是调用b()时创建的堆栈框架。这意味着只有一个可能的函数b(),但是对b()的许多调用会创建许多堆栈框架)。
b()
中的所有变量都成为
c()
的局部变量,而没有其他任何变量。名为
c()
的函数无法访问它们。
c
时,如下所示:
var c = function {/* new function */}
somewhere in RAM:
┌╶╶╶╶╶╶╶╶╶┐
┆ var bb ┆
└╶╶╶╶╶╶╶╶╶┘
The stack:
┌────────┐ ┌╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶┐
│ var c╶╶├╶╶╶╶╶╶╶╶╶╶╶┆ /* new function */ ┆
╞════════╡ └╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶┘
┆ ┆
b()
所属的作用域无权访问,因此无法从对
c
的调用中重新获得对堆栈框架的访问权限。
cfg
对象。
// WARNING: Private!
a._cfg = {
currency: 'GBP',
exponent: 2
};
关于javascript无法访问私有(private)属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26061856/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
PowerShell Web Access 允许您通过 Web 浏览器运行 PowerShell cmdlet。它显示了一个基于 Web 的控制台窗口。 有没有办法运行 cmdlet 而无需在控制台窗
我尝试在无需用户登录的情况下访问 Sharepoint 文件。 我可以通过以下任一方式获取访问 token 方法一: var client = new RestClient("https://logi
我目前正在尝试通过 Chrome 扩展程序访问 Google 服务。我的理解是,对于 JS 应用程序,Google 首选的身份验证机制是 OAuth。我的应用目前已成功通过 OAuth 向服务进行身份
假设我有纯抽象类 IHandler 和派生自它的类: class IHandler { public: virtual int process_input(char input) = 0; };
我有一个带有 ThymeLeaf 和 Dojo 的 Spring 应用程序,这给我带来了问题。当我从我的 HTML 文件中引用 CSS 文件时,它们在 Firebug 中显示为中止。但是,当我通过在地
这个问题已经有答案了: JavaScript property access: dot notation vs. brackets? (17 个回答) 已关闭 6 年前。 为什么这不起作用? func
我想将所有流量重定向到 https,只有 robot.txt 应该可以通过 http 访问。 是否可以为 robot.txt 文件创建异常(exception)? 我的 .htaccess 文件: R
我遇到了 LinkedIn OAuth2: "Unable to verify access token" 中描述的相同问题;但是,那里描述的解决方案并不能解决我的问题。 我能够成功请求访问 toke
问题 我有一个暴露给 *:8080 的 Docker 服务容器. 我无法通过 localhost:8080 访问容器. Chrome /curl无限期挂断。 但是如果我使用任何其他本地IP,我就可以访
我正在使用 Google 的 Oauth 2.0 来获取用户的 access_token,但我不知道如何将它与 imaplib 一起使用来访问收件箱。 最佳答案 下面是带有 oauth 2.0 的 I
我正在做 docker 入门指南:https://docs.docker.com/get-started/part3/#recap-and-cheat-sheet-optional docker-co
我正在尝试使用静态 IP 在 AKS 上创建一个 Web 应用程序,自然找到了一个带有 Nginx ingress controller in Azure's documentation 的解决方案。
这是我在名为 foo.js 的文件中的代码。 console.log('module.exports:', module.exports) console.log('module.id:', modu
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用 MGTwitterEngine"将 twitter 集成到我的应用程序中。它在 iOS 4.2 上运行良好。当我尝试从任何 iOS 5 设备访问 twitter 时,我遇到了身份验证 to
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用以下 API 列出我的 Facebook 好友。 https://graph.facebook.com/me/friends?access_token= ??? 我想知道访问 token 过
401 Unauthorized - Show headers - { "error": { "errors": [ { "domain": "global", "reas
我已经将我的 django 应用程序部署到 heroku 并使用 Amazon s3 存储桶存储静态文件,我发现从 s3 存储桶到 heroku 获取数据没有问题。但是,当我测试查看内容存储位置时,除
我是一名优秀的程序员,十分优秀!