tes*_*dtv 24 javascript oop prototype prototypal-inheritance
我有一个JavaScript函数对象;
var addNum = function(num1, num2) {
return num1 + num2;
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我尝试访问
addNum.divide()
Run Code Online (Sandbox Code Playgroud)
我想了解上述代码的原型链.我读到在上面的例子中,addNum将被搜索divide(),然后是Function.prototype,最后是Object.prototype.
但我的问题是在上面的例子中,addNum如何搜索divide()
它是指类似的东西吗?
var addNum = function(num1, num2) {
this.divide = function(){}
return num1 + num2;
}
Run Code Online (Sandbox Code Playgroud)
我无法理解addNum将被搜索为divide()的行
请帮我理解一下.
Kei*_*ris 51
我不确定这会回答你的问题,但可能会给你一些见解.请考虑以下示例:
var Person = (function () {
var Person = function (name) {
this.name = name;
}
Person.greet = function () {
console.log("Hello!");
}
Person.prototype = {
greet: function () {
console.log('Hello, my name is ' + this.name);
}
};
return Person;
})();
var bob = new Person("Bob");
Person.greet(); // logs "Hello!"
bob.greet(); // logs "Hello, my name is Bob
Run Code Online (Sandbox Code Playgroud)
函数对象"Person"具有直接'greet'属性,它是一个Function.在OOP方面,您几乎可以将其视为可以直接从Person Function(Person.greet())调用的静态方法.从Person构造函数"实例化"person对象后,新对象"bob"现在从Person.prototype对象引用它的方法.现在当你调用bob.greet()时,它使用原型对象中的greet函数.
希望有所帮助.
Eli*_*gem 20
正如你自己所说:你有一个功能对象.函数是JS中的对象,就像对象文字,数组或其他任何东西一样:可以随意为函数分配属性和方法:
var someAnonFunction = function(foo)
{
console.log(this);
console.log(this === someAnonFunction);//will be false most of the time
};
someAnonFunction.x = 123;//assign property
someAnonFunction.y = 312;
someAnonFunction.divide = function()
{
console.log(this === someAnonFunction);//will be true most of the time
return this.x/this.y;//divide properties x & y
};
someAnonFunction.divide();
Run Code Online (Sandbox Code Playgroud)
在这种情况下,引用的函数对象someAnonFunction已被赋予对匿名函数的引用,称为divide(好吧,对匿名函数的引用无论如何被称为除法).所以这里根本没有原型参与.请注意,就像你自己说的那样:所有对象都可以追溯到Object.prototype,试试这个:
console.log(someAnonFunction.toString === Function.prototype.toString);//functions are stringified differently than object literals
console.log(someAnonFunction.hasOwnProperty === Object.prototype.hasOwnProperty);//true
Run Code Online (Sandbox Code Playgroud)
或者,这可能更清楚:一个方法/属性调用如何解析为JS中的值的简单方案:
[ F.divide ]<=========================================================\ \
F[divide] ===> JS checks instance for property divide | |
/\ || | |
|| || --> property found @instance, return value-------------------------------| |
|| || | |
|| ===========> Function.prototype.divide could not be found, check prototype | |
|| || | |
|| ||--> property found @Function.prototype, return-----------------------| |
|| || | |
|| ==========> Object.prototype.divide: not found check prototype? | |
|| || | |
|| ||--> property found @Object.prototype, return---------------------|_|
|| || |=|
|| =======>prototype is null, return "undefined.divide"~~~~~~~~~~~~~~~|X|
|| \ /
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< TypeError can't read property 'x' of undefined
Run Code Online (Sandbox Code Playgroud)
因此,如果你想让上面的代码使用原型,你将不得不增加一个原型(在这种情况下,Function.prototype).要知道这不是推荐的,事实上改变"原生"原型通常是不受欢迎的.仍然:
Function.prototype.divide = function (a, b)
{
a = +(a || 0);//coerce to number, use default value
b = +(b || 1) || 1;//division by zeroe is not allowed, default to 1
return a/b;
};
function someFunction ()
{
return 'someString';
};
var another = function(a, b)
{
return a + b;
};
someFunction.divide(12, 6);//will return 2
another.divide(12, 4);//3
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,将扫描由名称(someFunction或another)引用的函数对象以查找divide未找到的属性.然而,它会扫描Function.prototype,找到这样的属性.
如果不是这样的话,JS也会检查Object.prototype,如果失败,它最终会抛出一个错误.
我前段时间就这个问题发表了很长的答案:
是什么让my.class.js如此之快?(处理原型链)
javascript中的对象和函数(函数的回顾<=>对象<=>构造函数)
JavaScript中这三种"类"定义模式之间有什么区别?(更多信息,仍然)
Javascript - 动态更改函数的内容(模糊地触及匿名函数,分配给变量和属性并更改其上下文)