Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/410.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 - Fatal编程技术网

“怎么说?”;这";Javascript中的关键字是否在对象文本中执行操作?

“怎么说?”;这";Javascript中的关键字是否在对象文本中执行操作?,javascript,Javascript,我看到了,但我看不出它回答了以下问题 鉴于此代码: var MyDate = function(date) { this.date = date; }; var obj1 = { foo: new Date(), bar: new MyDate(this.foo) // this.foo is undefined }; var obj2 = {}; obj2.foo = new Date(); obj2.bar = new MyDate(this.foo); /

我看到了,但我看不出它回答了以下问题

鉴于此代码:

var MyDate = function(date) {
    this.date = date;
};

var obj1 = {
    foo: new Date(),
    bar: new MyDate(this.foo)  //  this.foo is undefined
};

var obj2 = {};
obj2.foo = new Date();
obj2.bar = new MyDate(this.foo);  //  this.foo is undefined

var obj3 = {
    foo: new Date(),
    bar: new MyDate(obj3.foo)
};

var obj4 = {};
obj4.foo = new Date();
obj4.bar = new MyDate(obj4.foo);

为什么前两次尝试都失败了,但最后两次成功了?如果
this
未绑定到当前对象文本,那么它绑定到了什么?

在Javascript中,只有函数调用才能建立新的
this
上下文。调用
foo.bar()
时,在
bar
函数中,
将绑定到
foo
;当您调用
foo()
时,它内部的
将绑定到
窗口
。对象文本构造函数不是方法调用,因此它不会以任何方式影响
;它仍然会引用它在对象文本之外引用的任何内容。

我认为您可能缺少函数和对象文本之间的一个关键区别:

函数体在函数被调用之前不会被求值

这意味着
this
的值取决于函数的调用方式。如果它作为对象上的方法调用(例如
someObj.someFunc()
),则
将指向函数体中的该对象。如果它作为独立函数调用(
someFunc()
)。主体中的代码将继承调用者环境中的任何
this
。但是无论哪种方式,定义函数时
this
的值都无关紧要


而对象文字只是一个表达式;如果出现
this
,并且它不在文本中包含的函数体中,那么它将是
this
在该表达式出现的代码点处的值。

this.foo
是未定义的,因为在所有示例中,
this
指的是全局
窗口
对象。此外,即使您尝试了
obj1.foo
,它仍将返回undefined,因为在计算整个表达式之前尚未创建属性。请尝试以下方法:

var obj1 = {
    foo: new Date(),
    bar: function() {
        return new MyDate( this.foo ); // will work
    }
};

它之所以有效,是因为当您调用
obj1.bar()
时,该对象已经创建完毕;因为您在一个函数中,
这个
对象将引用当前对象。

Javascript是一种后期绑定语言。事实上,现在已经很晚了。
这个
不仅在编译时没有绑定,甚至在运行时也没有绑定(就像大多数其他后期绑定语言一样)。在javascript中,
在调用期间绑定

绑定规则与大多数其他OO语言有很大的不同,这就是为什么它似乎让很多不熟悉javascript的人感到困惑的原因

基本上,在代码中使用
this
的方式和位置不会影响
this
的行为(无论它是独立函数还是对象文本等)。决定
this
值的是如何调用函数

这些规则是:

1-当函数作为构造函数调用时,将创建一个新对象,并且
将绑定到该对象。例如:

function Foo () {
    this.bar = 1; // when called with the new keyword
                  // this refers to the object just created
}
new Foo().bar;
foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this refers to foo when called as foo.baz()
}
foo.baz();
bar = 1;
alert(this.bar); // this refers to the global object
foo = {
    bar: this.bar // also global object
}
function foofoo () {
    alert(this.bar); // also refers to the global object
}
foofoo();
foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this would normally be foo but if this
                     // function is assigned to an event it would
                     // point to the element that triggered the event
}
somediv.bar = 2;
somediv.onclick = foo.baz; // clicking on somedive alerts 2 instead of 1
cat = {
    type: "cat",
    explain: function () {
        return "I am a " + this.type;
    }
}
dog = {
    type: "dog"
}
cat.explain.call(dog); // returns "I am a dog"
function explain () {
    return "I am a " + this.type;
}
dog = {
    type: "dog"
}
var dog_explain = explain.bind(dog);
dog_explain(); // returns "I am a dog"
2-当被称为对象方法
时,此
指方法所属的对象。基本上是最后一个点之前的名称。例如:

function Foo () {
    this.bar = 1; // when called with the new keyword
                  // this refers to the object just created
}
new Foo().bar;
foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this refers to foo when called as foo.baz()
}
foo.baz();
bar = 1;
alert(this.bar); // this refers to the global object
foo = {
    bar: this.bar // also global object
}
function foofoo () {
    alert(this.bar); // also refers to the global object
}
foofoo();
foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this would normally be foo but if this
                     // function is assigned to an event it would
                     // point to the element that triggered the event
}
somediv.bar = 2;
somediv.onclick = foo.baz; // clicking on somedive alerts 2 instead of 1
cat = {
    type: "cat",
    explain: function () {
        return "I am a " + this.type;
    }
}
dog = {
    type: "dog"
}
cat.explain.call(dog); // returns "I am a dog"
function explain () {
    return "I am a " + this.type;
}
dog = {
    type: "dog"
}
var dog_explain = explain.bind(dog);
dog_explain(); // returns "I am a dog"
3-如果在任何函数外部使用或函数未作为方法调用,则此
引用全局对象。javascript规范没有给全局对象命名,只是说它存在,但对于浏览器来说,它传统上被称为
window
。例如:

function Foo () {
    this.bar = 1; // when called with the new keyword
                  // this refers to the object just created
}
new Foo().bar;
foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this refers to foo when called as foo.baz()
}
foo.baz();
bar = 1;
alert(this.bar); // this refers to the global object
foo = {
    bar: this.bar // also global object
}
function foofoo () {
    alert(this.bar); // also refers to the global object
}
foofoo();
foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this would normally be foo but if this
                     // function is assigned to an event it would
                     // point to the element that triggered the event
}
somediv.bar = 2;
somediv.onclick = foo.baz; // clicking on somedive alerts 2 instead of 1
cat = {
    type: "cat",
    explain: function () {
        return "I am a " + this.type;
    }
}
dog = {
    type: "dog"
}
cat.explain.call(dog); // returns "I am a dog"
function explain () {
    return "I am a " + this.type;
}
dog = {
    type: "dog"
}
var dog_explain = explain.bind(dog);
dog_explain(); // returns "I am a dog"
4-在事件处理程序(如onclick等)中
指触发事件的DOM元素。或者对于与DOM无关的事件,如
setTimeout
XMLHTTPRequest
引用全局对象。例如:

function Foo () {
    this.bar = 1; // when called with the new keyword
                  // this refers to the object just created
}
new Foo().bar;
foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this refers to foo when called as foo.baz()
}
foo.baz();
bar = 1;
alert(this.bar); // this refers to the global object
foo = {
    bar: this.bar // also global object
}
function foofoo () {
    alert(this.bar); // also refers to the global object
}
foofoo();
foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this would normally be foo but if this
                     // function is assigned to an event it would
                     // point to the element that triggered the event
}
somediv.bar = 2;
somediv.onclick = foo.baz; // clicking on somedive alerts 2 instead of 1
cat = {
    type: "cat",
    explain: function () {
        return "I am a " + this.type;
    }
}
dog = {
    type: "dog"
}
cat.explain.call(dog); // returns "I am a dog"
function explain () {
    return "I am a " + this.type;
}
dog = {
    type: "dog"
}
var dog_explain = explain.bind(dog);
dog_explain(); // returns "I am a dog"
5-最后,当使用
call()
apply()
方法调用函数时,
可以将此
重新分配给任何对象(谷歌“mdn function.prototype.call”)。这样,javascript中的任何对象都可以借用/窃取其他对象的方法。例如:

function Foo () {
    this.bar = 1; // when called with the new keyword
                  // this refers to the object just created
}
new Foo().bar;
foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this refers to foo when called as foo.baz()
}
foo.baz();
bar = 1;
alert(this.bar); // this refers to the global object
foo = {
    bar: this.bar // also global object
}
function foofoo () {
    alert(this.bar); // also refers to the global object
}
foofoo();
foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this would normally be foo but if this
                     // function is assigned to an event it would
                     // point to the element that triggered the event
}
somediv.bar = 2;
somediv.onclick = foo.baz; // clicking on somedive alerts 2 instead of 1
cat = {
    type: "cat",
    explain: function () {
        return "I am a " + this.type;
    }
}
dog = {
    type: "dog"
}
cat.explain.call(dog); // returns "I am a dog"
function explain () {
    return "I am a " + this.type;
}
dog = {
    type: "dog"
}
var dog_explain = explain.bind(dog);
dog_explain(); // returns "I am a dog"
在现代javascript实现中,有了
Function.bind()
,我们现在有了另一条规则:

6-函数还可以使用
bind()
方法将
显式绑定到对象。
bind
方法返回函数的新实例,其中
绑定到传递给
bind
的参数。例如:

function Foo () {
    this.bar = 1; // when called with the new keyword
                  // this refers to the object just created
}
new Foo().bar;
foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this refers to foo when called as foo.baz()
}
foo.baz();
bar = 1;
alert(this.bar); // this refers to the global object
foo = {
    bar: this.bar // also global object
}
function foofoo () {
    alert(this.bar); // also refers to the global object
}
foofoo();
foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this would normally be foo but if this
                     // function is assigned to an event it would
                     // point to the element that triggered the event
}
somediv.bar = 2;
somediv.onclick = foo.baz; // clicking on somedive alerts 2 instead of 1
cat = {
    type: "cat",
    explain: function () {
        return "I am a " + this.type;
    }
}
dog = {
    type: "dog"
}
cat.explain.call(dog); // returns "I am a dog"
function explain () {
    return "I am a " + this.type;
}
dog = {
    type: "dog"
}
var dog_explain = explain.bind(dog);
dog_explain(); // returns "I am a dog"
ECMAscript 5引入了strict模式,该模式改变了函数的含义,这些函数不是作为方法调用的,也不是通过call或apply调用的,因此我们必须添加一个新规则:

7-在严格模式下,
不允许此
引用全局对象(浏览器中的窗口)。因此,当函数未作为方法调用或
未通过
调用
应用
绑定
手动绑定到任何对象时,
将变为
未定义

"use strict";
function foo () {
    return this;
}
foo(); // returns undefined instead of the global object
ECMAscript 6引入了箭头函数。箭头函数通过提前绑定来更改其行为

8-在箭头函数中,
在声明函数时绑定。因此,以下代码中的

var x = () => {return this};
var x = function () {return this}.bind(this);
其行为与声明函数类似,如以下代码所示:

var x = () => {return this};
var x = function () {return this}.bind(this);
请注意,由于箭头函数中的
在声明函数时已绑定,因此如果要使用继承,则不能使用箭头函数。这是因为函数中的
this
将始终指向父对象,而不会指向子对象。这意味着使继承与arrow函数一起工作的唯一方法是重写所有arrow函数