我正在学习JavaScript而且我遇到了这个片段,它演示了类型检测:
var toClass = {}.toString // Copy a reference to toString for objects into toClass variable
alert( toClass.call( [1,2] ) ) // [object Array]
alert( toClass.call( new Date ) ) // [object Date]
我不明白第一行的空花括号是什么,所以我将它们删除如下:
var toClass = toString
代码仍然有效。 但是在下面的代码中,
function getAge () {
alert(this.age);
}
var p1 = {
age:1
};
var tellAge=getAge;
tellAge.call(p1); //1
如果我将var tellAge=getAge
更改为var tellAge={}.getAge
,则会收到错误:无法读取未定义的属性“call”。
为什么是这样?是因为toString
是内置函数吗?
答案 0 :(得分:7)
是因为toString是一个内置函数
不完全是因为javascript中的Object
和window
都有toString
方法。
{}
中的{}.toString
代表javascript中的新对象。对象具有toString
方法,这就是您创建对。
如果省略{}
它等同于window.toString
,幸运的是window
对象本身有toString
方法。所以一切都继续有效。
当您执行{}.getAge
时,您告诉口译员从对象中获取getAge
方法,该方法不存在,将tellAge
设置为undefined
,这会导致错误cannot read property "call" of undefined
答案 1 :(得分:1)
{}
会返回Object
(1)类型的新对象。toString()
返回表示对象(2)的字符串。Object
类型的对象,toString()
应返回值[object Object]
。call()
执行具有给定this
值的方法和单独提供的参数(3)。Window
对象。在此类函数中使用this
始终引用Window
对象。现在,让我们回到你的代码,好吗?!
var toClass = {}.toString
首先创建一个Object
类型的通用对象。然后它返回方法toString
(方法本身,而不是返回值。
这意味着toClass现在是一个函数。它使用对象{}
作为this
值。因此,如果您只是运行toClass()
,则应始终获得值[object Object]
。
现在,这是棘手的一点!
执行此命令:
toClass.call( [1,2] )
这里发生了什么?嗯,这类似于调用toClass()
,但您的this
值不再是{}
。相反,它会被[1,2]
(4)取代。这就是为什么你得到[object Array]
的结果!
现在接受此命令:
toClass.call( new Date )
这里发生了什么?嗯,同样的事情,真的。这与调用toClass()
或toClass.call( [1,2] )
类似,只是您的this
值被Date
(5)类型的对象替换。这就是为什么你得到[object Date]
的结果!
现在,请使用此功能:
function getAge () {
alert(this.age);
}
这里发生了什么?好吧,此函数只会警告方法中age
值的属性this
。默认情况下,此属性未知,因为this
值为Window
且Window
对象没有age
属性。
现在,请执行以下命令:
var p1 = {
age:1
};
在这里,您创建一个只有一个属性的对象。该属性为age
,其值为1.
现在,请执行以下命令:
var tellAge=getAge;
在此,您将函数getAge
指定给变量tellAge
。默认情况下,两个函数都使用相同的this
值,即Window
对象。
tellAge.call(p1);
这里发生了什么?好吧,它与调用tellAge()
或getAge()
几乎相同,只是您的this
值不再是Window
。相反,它被p1
取代。结果是1
,因为对象p1
有一个属性age
,该属性的值为1!
现在,让我们检查以下命令:
var tellAge={}.getAge
为什么会产生错误?你在这里要做的是创建一个Object
类型的通用对象。虽然默认情况下它具有toSting
方法(在原型(6)中定义),但它没有getAge
方法。这就是你收到错误的原因。
现在请使用以下代码:
var p2 = {
age : 18
};
var p3 = {
age : 25
};
var FObject = {
getage : function() {
return this.age;
}
};
var tellAge = FObject.getage;
alert( tellAge.call(p2) ); //18
alert( tellAge.call(p3) ); //25
这是做什么的?好吧:
p2
的对象,该对象具有值为18的age
属性。p3
的对象,该对象具有值为25的age
属性。FObject
的对象对象,该对象具有getage
方法。FObject.getage
分配给变量tellAge
。tellAge.call(p2)
。这与调用tellAge()
类似,只是您的this
值被对象p2
替换。这就是为什么你得到18
的结果!tellAge.call(p3)
。这与调用tellAge()
或tellAge.call(p2)
类似,只是您的this
值被对象p3
替换。这就是为什么你得到25
的结果!我相信最后一个例子很好地概述了你正在研究的行为。
参考文献:
答案 2 :(得分:1)
哦,我的...在很短的时间内要回答很多事情......但是你还有很长的路要走JavaScript,但是你会爱上它...... < / p>
1)对象表示法。你应该google for JSON。
对象表示法意味着,您可以使用与JavaScript相关的特定格式定义数据。
对象表示法中的{}表示一个对象......更具体地说,这已经是一个对象的实例。
你也可以用普通的javascript写这个,它看起来像这样:
new Object()
2)职能是一等公民。
嗯,功能确实是JS生态系统中非常有价值的资产。这意味着你可以基本上做任何你想象的事情。这包括复制对属于&#34;属于&#34;的函数的引用。另一个对象。
{}。toString是一个函数。您通常会通过执行{} .toString()
来调用它相反,只需在变量中复制对函数的引用即可。在这种情况下,你&#34;存储&#34;变量&#34; toClass&#34;
中的函数
3)原型链。你应该谷歌,好吧,原型链哈哈。
原型链,简单来说就是&#34;喜欢&#34;类继承。所以这意味着如果一个A类有一个方法&#34; blah&#34;而B班是一个孩子&#34; A级,这个,好吧,也有方法&#34; blah&#34;。
在JS世界中,原型链的顶部是&#34; Object&#34;。许多函数已经在Object的原型中定义。包括&#34; toString&#34;
4)广义相对论问题...... a.k.a. this,call,and apply。
由于函数是一等公民,它们基本上可以存在,甚至不属于特定的对象实例。
这意味着,您可以选择要在哪个此上下文中调用该函数。
默认情况下,当您调用似乎&#34;附加&#34;对象,该对象成为该函数调用的 this 上下文:
{}.toString() // This executes toString in the context of {}
但正如我所说,你可以选择功能实际执行的位置。为此,方法&#34;呼叫&#34;并且&#34;申请&#34;存在。
我们之前的例子可以翻译成:
Object.prototype.toString.call({}) // This executes toString in the context of {}
5)环境中的全局对象。
这不是一个简单的主题,因为现在JavaScript不仅在浏览器上运行,而且在服务器上运行...... NodeJS就是一个很好的例子。
假设您在浏览器中运行此操作...有一个名为窗口的全局对象
您基本上可以调用全局对象中的任何函数。
所以toString相当于 window .toString,window是Object的后代,它也会从Object.prototype中获取方法。
现在回答
getAge 未在Object.prototype中定义,因此您无法调用不存在的函数。
答案 3 :(得分:0)
刚刚做了这个例子,向你说清楚。 Jsfiddle
var toClass = {}.toString; // type detection
function person(age){
this.age = age;
this.getAgePlusOne = function(){
return this.age + 1;
};
}
var you = new person(20); // create a new person object and set age propery to 20
console.log(you);
var yourAge = you.getAgePlusOne(); // call created person object's function getAgePlusOne() to retrieve value
console.log(yourAge);
console.log(toClass.call(you)); // object
console.log(toClass.call(you.getAgePlusOne)); //function