Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 验证我对范围链的理解_Javascript_Scope Chain - Fatal编程技术网

Javascript 验证我对范围链的理解

Javascript 验证我对范围链的理解,javascript,scope-chain,Javascript,Scope Chain,(问题1) 在Flanagan的JS权威指南中,他定义了函数方法bind(),以防它不可用(在ECMAScript 3中不可用) 看起来是这样的: function bind(f, o) { if (f.bind) return f.bind(o); // Use the bind method, if there is one else return function() { // Otherwise, bind it like this

(问题1) 在Flanagan的JS权威指南中,他定义了
函数
方法
bind()
,以防它不可用(在ECMAScript 3中不可用)

看起来是这样的:

function bind(f, o) {
    if (f.bind) return f.bind(o);     // Use the bind method, if there is one
    else return function() {          // Otherwise, bind it like this
        return f.apply(o, arguments);
    };
}
他用一个例子来说明它的用法(我已经修改了这个例子,将第三行从
f.bind(o)
)改为:

当我第一次看到这一点时,我想“arguments不是指我们正在定义的bind函数中的arguments变量吗?但是我们想要最终应用它的函数的arguments属性,就像上面例子中的g一样…”

我验证了他的示例是否确实有效,并推测在上面的
var g=bind(f,o)
之前,不会对行
return f.apply(o,arguments)
求值。也就是说,我想,当你返回一个函数时,你只是返回该函数的源代码,不是吗?直到它被评估?因此,我尝试了一个稍微不同的bind版本来测试这个理论:

function mybind2(f, o) {
    var arguments = 6;
    return function() {          // Otherwise, bind it like this
        return f.apply(o, arguments);
    };
}
如果它只是返回未赋值的函数源,那么在以后求值时它不可能存储
arguments=6
,对吗?经过检查,我仍然得到了
g(2)
=>3。但是后来我意识到——如果它只是返回未赋值的代码,那么
returnf.apply(o,arguments)
中的
o
是如何传递的

所以我决定必须发生的是:

o
arguments
变量(即使
arguments
等于6)也会传递给函数。只是当函数
g
最终被调用时,
arguments
变量被解释器重新定义为
g
(在
g(2)
中)的参数,因此我试图传递的参数的原始值被替换。但这意味着在此之前它是以文本形式存储函数的,因为否则
o
arguments
将只是程序中的数据,而不是可以覆盖的变量。这个解释正确吗

(问题2)在同一页的前面,他定义了以下函数,该函数使用
apply
方法跟踪函数以进行调试:

function trace(o, m) {
    var original = o[m];  // Remember original method in the closure.
    o[m] = function() {   // Now define the new method.
        console.log(new Date(), "Entering:", m);      // Log message.
        var result = original.apply(this, arguments); // Invoke original.
        console.log(new Date(), "Exiting:", m);       // Log message.
        return result;                                // Return result.
    };
}
这里的
this
不是指我们正在定义的函数,而不是对象
o
?还是这两件事是一回事?

问题1 对于您的第一个问题,让我们简化示例,以便清楚地了解正在执行的操作:

function bind(func, thisArg) {
    return function () {
        return func.apply(thisArg, arguments);
    };
}
这里发生的事情是创建一个闭包,允许访问原始函数和传递的
this
的值。返回的匿名函数将保持原始函数在其作用域中,其结果如下所示:

var func = function () {};
var thisArg = {};
func.apply(thisArg, [/*arguments*/]);
关于
参数
的问题,该变量在创建的所有函数的作用域中都是隐式定义的,因此内部
参数
将覆盖外部
参数
,使其按预期工作

问题2 你的问题在于你对
this
的后期绑定的误解——对于那些习惯于使用同样有自己的
this
关键字的面向对象语言的人来说,这是关于JavaScript最令人困惑的事情之一。
this
的值仅在调用时设置,调用该值的位置定义了调用该值时的
this
的值。它只不过是调用函数时父对象所在位置的值
此值被覆盖的情况除外

例如,请参见以下内容:

function a() {return this;};
a(); // global object;
var b = {};
b.a = a;
b.a(); // object b
如果定义函数时设置了
,则调用
b.a
将生成全局对象,而不是
b
对象。让我们也来简化给定的第二个函数:

function trace(obj, property) {
    var method = obj[property];  // Remember original method in the closure.
    obj[property] = function () {   // Now define the new method.
        console.log(1); // Log message.
        // Invoke original method and return its result
        return original.apply(this, arguments);
    };
}
在这种情况下,原始方法存储在闭包中。分配给方法最初所在的对象不会覆盖
方法
对象。与普通的方法赋值一样,
这个
值的原理仍然是一样的——它将返回父对象,而不是您定义的函数。如果你做一个简单的作业:

var obj = {};
obj.foo = function () { return this; };
obj.foo(); // obj
它执行预期的操作,在调用时返回父对象。在这方面,将代码放在嵌套函数中没有任何区别

一些好资源 如果你想了解更多关于用JavaScript编写代码的知识,我强烈建议你看看Cody Lindley的文章——它详细介绍了
这个
关键字在不同上下文中的行为以及你可以使用它做的事情。

问题1 对于您的第一个问题,让我们简化示例,以便清楚地了解正在执行的操作:

function bind(func, thisArg) {
    return function () {
        return func.apply(thisArg, arguments);
    };
}
这里发生的事情是创建一个闭包,允许访问原始函数和传递的
this
的值。返回的匿名函数将保持原始函数在其作用域中,其结果如下所示:

var func = function () {};
var thisArg = {};
func.apply(thisArg, [/*arguments*/]);
关于
参数
的问题,该变量在创建的所有函数的作用域中都是隐式定义的,因此内部
参数
将覆盖外部
参数
,使其按预期工作

问题2 你的问题在于你对
this
的后期绑定的误解——对于那些习惯于使用同样有自己的
this
关键字的面向对象语言的人来说,这是关于JavaScript最令人困惑的事情之一。
this
的值仅在调用时设置,调用该值的位置定义了调用该值时的
this
的值。它只是调用函数时父对象所在位置的值,但o除外
var arguments = 42;
function foo() {
    console.log(arguments);
}
foo(1, 2);