Javascript:理解原型链
Javascript: Understanding Prototype chain
我创建了一个简单的类,如下:
var Class = function() {};
Class.prototype.testObj = {a:2, b:3};
现在如果我做console.log(Class.testObj)
,我得到undefined
。但是如果我像这样创建这个类的实例:
var instance = new Class();
console.log(instance.testObj)
我得到了预期的输出。
在我的理解中,所有变量都被视为对象并具有原型属性。当在对象中没有找到某个键时,遍历原型链以查找键值对。但是对于Class,它没有遍历原型链。
我错过了什么?new
关键字还做了什么使属性可访问?
-
您必须清楚
Class()
是您的constructor
,而不是instance object
。所以Class.testObject
会返回undefined
因为Class
没有property
-
您可以将
prototype
视为对象的配方。几乎每个函数都有一个prototype
属性,在创建新实例期间使用,并且prototype
在所有对象实例中共享 -
构造函数就是与
new
一起用来创建对象的函数 -
当你这样做
var instance = new Class();
这意味着你正在创建Class
的实例对象,因此instance
将继承Class
的prototype
属性 测试: console.log(instance instanceof Class); // => true console.log(instance.constructor === Class); // => true console.log(Object.prototype.isPrototypeOf(Class)); // => true console.log(Class.prototype.isPrototypeOf(instance)); // => true
无论何时创建对象(例如函数),它都继承自object构造函数,因此
var Class = function() {};
是一个对象,它有自己的prototype
属性,可以通过
Class.prototype
,你可以用
在prototype
对象上创建新的属性Class.prototype.testObj = {a:2, b:3};
如果你想访问它,你实际上必须执行
console.log(Class.prototype.testObj)
,这是一个添加到Class
的prototype
属性的属性。
当您使用new
关键字时,一些神奇的事情发生了,创建了一个全新的对象(称为实例),并且该对象继承自Class.prototype
,从docs
当代码new Class(…)被执行时,会发生以下事情:
继承Class.prototype创建一个新对象
使用指定的参数调用构造函数Class和
this
绑定到新创建的对象。new Class等价于new Class(),即如果没有指定参数列表,则调用Class没有参数。构造函数返回的对象成为结果全新的表达方式。如果构造函数没有显式返回一个对象,使用步骤1中创建的对象代替。(通常构造函数不返回值,但如果它们想要覆盖正常的对象创建,它们可以选择这样做过程。)
您误解了Class
和Class.prototype
的关系。
Class
是构造函数。严格地说,JavaScript不区分构造函数和通用函数,但现在这并不重要。Class.prototype
是Class的实例的原型。也就是说,当您实例化类var x = new Class()
时,Class.prototype
作为委托对象附加到x
上。
这意味着对x的查找将沿着委托链传播,并在原型实例上引用变量。
在我的理解中,所有变量都被视为对象并具有prototype属性。
这是不正确的。JavaScript有很多基本类型,只有函数有一个名为"prototype"的属性。原型委托只有在使用new
和构造函数或ECMAScript 5 object.create()
符号创建时才附加到引用类型(对象、数组和函数)。
Class
确实有一个原型委托,因为它是Function()
的一个实例。委托函数方法的一个实例是apply()
。
简单地说,Class
不是Class
的实例,它是Function
的实例,那么它为什么要继承Class.prototype
呢?Class
原型链的第一个环节是Function.prototype
。
我们可以看到,如果我们从Function.prototype
中选择一个函数,比如call
,它存在于Class
中。
typeof Class.call; //function
对象实例用它们的构造函数的原型建立它们的原型链。因此,只有作为Class
实例的对象才会使用Class.prototype
来设置它们的原型链。
添加对象到prototype
,
如果您执行console.log(Class.prototype)
,您将看到对象。
new
关键字实例化对象,这将显示附加到其原型的属性作为实例化对象的属性。
因为新实例化的对象实际上继承了父对象的prototype
,而不是父对象本身。
- 使用“;这个“;JavaScript原型方法中的关键字
- 如何从对象的原型方法访问JavaScript对象属性
- Node.js中的JavaScript原型对象效率
- 为什么要返回'这'在导致循环的JavaScript原型中
- 原型和用法 Javascript
- JavaScript对象不是从原型链继承的
- javascript对象原型与jquery冲突
- 原型Javascript中的错误“;类别“-不是函数和未定义的变量
- 从字符串原型javascript获取字符串值
- 原型JavaScript Event.observe-如何观察可能存在或不存在的元素
- 与原型javascript冲突
- 为什么原型JavaScript在这种情况下不起作用
- 使用原型JavaScript - 最佳实践
- 添加到另一个原型实例的原型:JavaScript
- 函数.原型Javascript
- 如何在选定的原型javascript中更新基于第一选择框的第二选择
- 原型Javascript框架-获取PHP响应
- 如何访问类原型Javascript中定义的事件处理程序中的类成员变量
- 原型 javascript 不显眼的点击事件添加到按钮
- 字符串vs数组原型Javascript