Javascript 为什么在类中的函数中设置'this.property'会生成新属性,而获取'this.property'会使用类属性?
我有一个javascript类,它有一个属性(Javascript 为什么在类中的函数中设置'this.property'会生成新属性,而获取'this.property'会使用类属性?,javascript,oop,object,Javascript,Oop,Object,我有一个javascript类,它有一个属性(已初始化)和一个函数(已初始化) 类定义: function Test() { this.is_initialized = { obj: { isInitialized: 'notyet' } }; this.isInitialized = function( ref ) { if ( !ref.obj ) { console.log( 'now: ' + JSON.st
已初始化)和一个函数(已初始化)
类定义:
function Test()
{
this.is_initialized = { obj: { isInitialized: 'notyet' } };
this.isInitialized = function( ref )
{
if ( !ref.obj )
{
console.log( 'now: ' + JSON.stringify( this.is_initialized ) );
/*line 9*/ this.is_initialized.obj.isInitialized = ref.isInitialized.toString();
console.log( ref );
}
else {
bluetoothle.isInitialized( this.isInitialized );
/*line 14*/ ref.obj = this.is_initialized.obj;
}
};
}
var t = new Test();
var r = {obj:{isInitialized:'nope'}};
t.isInitialized(r);
// console.log( 'now: ' + JSON.stringify( this.is_initialized ) ); on line 8:
// now: {"obj":{"isInitialized":"false"}}
// console.log( ref ); on line 10:
// Object {isInitialized: false}
console.log(JSON.stringify(r));
// {"obj":{"isInitialized":"notyet"}}
console.log(JSON.stringify(t));
// {"is_initialized":{"obj":{"isInitialized":"notyet"}}}
Bluetooth.isInitialized
是cordova插件中的一个函数(回答此问题不需要了解cordova),它返回一个对象{isInitialized:true/false}
,并将传递第一个if
-语句,而我对isInitialized()
的调用将执行else
问题:
function Test()
{
this.is_initialized = { obj: { isInitialized: 'notyet' } };
this.isInitialized = function( ref )
{
if ( !ref.obj )
{
console.log( 'now: ' + JSON.stringify( this.is_initialized ) );
/*line 9*/ this.is_initialized.obj.isInitialized = ref.isInitialized.toString();
console.log( ref );
}
else {
bluetoothle.isInitialized( this.isInitialized );
/*line 14*/ ref.obj = this.is_initialized.obj;
}
};
}
var t = new Test();
var r = {obj:{isInitialized:'nope'}};
t.isInitialized(r);
// console.log( 'now: ' + JSON.stringify( this.is_initialized ) ); on line 8:
// now: {"obj":{"isInitialized":"false"}}
// console.log( ref ); on line 10:
// Object {isInitialized: false}
console.log(JSON.stringify(r));
// {"obj":{"isInitialized":"notyet"}}
console.log(JSON.stringify(t));
// {"is_initialized":{"obj":{"isInitialized":"notyet"}}}
为什么第9行的这个.is_initialized
在函数is initialized
中创建一个新属性,而第14行的这个.is_initialized
使用Test()中的属性is_initialized
它不应该同时使用Test()
中的属性,还是在isInitialized()中使用(新)变量
如果它“只是”这样,我能做些什么来处理它
我运行的代码:
function Test()
{
this.is_initialized = { obj: { isInitialized: 'notyet' } };
this.isInitialized = function( ref )
{
if ( !ref.obj )
{
console.log( 'now: ' + JSON.stringify( this.is_initialized ) );
/*line 9*/ this.is_initialized.obj.isInitialized = ref.isInitialized.toString();
console.log( ref );
}
else {
bluetoothle.isInitialized( this.isInitialized );
/*line 14*/ ref.obj = this.is_initialized.obj;
}
};
}
var t = new Test();
var r = {obj:{isInitialized:'nope'}};
t.isInitialized(r);
// console.log( 'now: ' + JSON.stringify( this.is_initialized ) ); on line 8:
// now: {"obj":{"isInitialized":"false"}}
// console.log( ref ); on line 10:
// Object {isInitialized: false}
console.log(JSON.stringify(r));
// {"obj":{"isInitialized":"notyet"}}
console.log(JSON.stringify(t));
// {"is_initialized":{"obj":{"isInitialized":"notyet"}}}
刚才发生的事情是:
- 我创建了一个Test()的新实例,并将其命名为
t
- 我在Test()中创建了一个匹配结构为
的对象,该对象已初始化,但具有不同的值
- 我用
r
作为参数调用函数
- 执行
else
中的代码
- 在调用回调时初始化带有
的异步函数
- 在现有
之间创建引用的函数已初始化和r
- 异步函数调用初始化的
并执行if
中的代码
- 它在第8行记录
this.is\u initialized
的当前值,在执行第9行之后,它以某种方式获得this.is\u initialized
- 第9行执行时,在
isInitialized()
内部创建名为的新变量,而我希望它在Test()
中设置已初始化
,而不是创建一个新变量,该变量在函数执行完毕后失效
- 它记录放入
this.is\u initialized.obj.isInitialized
的对象
- 我记录r并查看它是否包含
Test.is\u initialized
的初始值
- 我记录t并看到
已初始化
的值仍为初始值
信息:
function Test()
{
this.is_initialized = { obj: { isInitialized: 'notyet' } };
this.isInitialized = function( ref )
{
if ( !ref.obj )
{
console.log( 'now: ' + JSON.stringify( this.is_initialized ) );
/*line 9*/ this.is_initialized.obj.isInitialized = ref.isInitialized.toString();
console.log( ref );
}
else {
bluetoothle.isInitialized( this.isInitialized );
/*line 14*/ ref.obj = this.is_initialized.obj;
}
};
}
var t = new Test();
var r = {obj:{isInitialized:'nope'}};
t.isInitialized(r);
// console.log( 'now: ' + JSON.stringify( this.is_initialized ) ); on line 8:
// now: {"obj":{"isInitialized":"false"}}
// console.log( ref ); on line 10:
// Object {isInitialized: false}
console.log(JSON.stringify(r));
// {"obj":{"isInitialized":"notyet"}}
console.log(JSON.stringify(t));
// {"is_initialized":{"obj":{"isInitialized":"notyet"}}}
若你们想亲自测试它来回答我的问题,为什么?我该怎么处理呢?但是需要一些bluetoothle的代码。I初始化
只需使用以下代码:
var bluetoothle = {isInitialized:function(){setTimeout(function(){func({isInitialized:false});},20);}};
// to execute:
bluetoothle.isInitialized(/*callbackfunction*/);
感谢您阅读这个长问题。您正处于一个函数中。在函数内部(除非声明为Test.prototype.isInitialized),“this”的作用域规则是不同的。这是ES6旨在消除的陷阱之一。(如果您在函数顶部添加了“使用严格”;大多数浏览器都会告诉您这一点。)
在测试中声明var self=this,并在内部函数中使用self,您应该会得到想要的结果@Skint已经说过很多了。是什么让你认为它会创建一个新的“变量”?这似乎取决于你的Bluetooth.i初始化的函数的实现。如果它真的是异步的,如您所说,那么第14行当然会在第9行之前执行。当您传递this.isInitialized
时,您只传递函数,而不是对象。因此,当它调用函数时(在测试代码中的setTimeout
回调中),它不知道原始对象是什么,因此它将this
的值设置为窗口
对象。因此,异步调用在使用this
时引用全局对象。因此,当您到达this.is_initialized.obj.isInitialized=
时,这应该根本不起作用,除非您定义了一个名为is_initialized
的全局变量。您的意思是bluetoothle.isInitialized(this.isInitialized.bind(this))代码>和var bluetoothle={isInitialized:function(func){…
?否则,您的代码不会毫无例外地执行。是的,我并没有告诉您您正在传递函数。我只是告诉您只传递函数,而不是对象。很高兴听到这有意义。“在函数内部,‘this’的作用域规则不同”?this
的作用域规则非常一致。与什么不同?@user1329482 Bergi是正确的,规则是相同的,但当我通过函数ass回调时,它是在bluetoothle
的范围内执行的,而不是Test()
。使用bluetoothle.isInitialized(this.isInitialized.bind(this));
(正如Bergi所说)给我修好了。@Bergi继续回答,要求你的代表,并为将来做标记visitors@ThisNameBetterBeAvailable:我已经链接了一个标准副本,没有我的答案:-)如果你仍然想让我得到代表,你可以对我的任何其他答案自由投票,但老实说,我不需要它