- 创建一个空对象
- 将空对象的proto指向构造函数的prototype
- 使用空对象作为上下文的调用构造函数
- function Person(name, age) {
- this.name = name;
- this.age = age;
- }
- 创建一个空对象:var obj = {}
- 将空对象的proto__`指向构造函数的 prototype:`obj.__proto = Person().prototype
- 使用空对象作为上下文调用构造函数:Person.call(obj)
检查JS对象之间的原型链接有很多种方法 。例如,Object.getPrototypeOf是一个返回任何给定对象原型的方法 。考虑以下代码:
var Person = { name: "noname", age: 0, greet: function() { console.log(`Hello ${this.name}`); }};var Tom = Object.create(Person);检查Person是否是Tom的原型:
var tomPrototype = Object.getPrototypeOf(Tom);console.log(tomPrototype === Person);// Output: true当然,如果使用构造函数调用构造对象,Object.getPrototypeOf也可以工作 。但是应该检查原型对象,而不是构造函数本身:
function Person(name, age) { this.name = name; this.age = age;}Person.prototype.greet = function() { console.log("Hello " + this.name);};var me = new Person("Valentino");var mePrototype = Object.getPrototypeOf(me);console.log(mePrototype === Person.prototype);// Output: true除了Object.getPrototypeOf之外,还有另一个方法isPrototypeOf 。该方法用于测试一个对象是否存在于另一个对象的原型链上,如下所示,检查 me 是否在 Person.prototype 上:
Person.prototype.isPrototypeOf(me) && console.log('Yes I am!')
instanceof运算符也可以用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置 。老实说,这个名字有点误导,因为JS中没有“实例” 。在真正的面向对象语言中,实例是从类创建的新对象 。请考虑Python中的示例 。咱们有一个名为Person的类,咱们从该类创建一个名为“tom”的新实例:
class Person(): def __init__(self, age, name): self.age = age; self.name = name; def __str__(self): return f'{self.name}'tom = Person(34, 'Tom')注意,在Python中没有new关键字 。现在,咱们可以使用isinstance方法检查tom是否是Person的实例
isinstance(tom, Person)// Output: TrueTom也是Python中“object”的一个实例,下面的代码也返回true:
isinstance(tom, object)// Output: True根据isinstance文档,“如果对象参数是类参数的实例,或者是它的(直接、间接或虚拟)子类的实例,则返回true” 。咱们在这里讨论的是类 。现在让咱们看看instanceof做了什么 。咱们将从JS中的Person函数开始创建tom(因为没有真正的类)
function Person(name, age) { this.name = name; this.age = age;}Person.prototype.greet = function() { console.log(`Hello ${this.name}`);};var tom = new Person(34, "Tom");使用isinstance方法检查tom是否是Person和 Object 的实例
if (tom instanceof Object) { console.log("Yes I am!");}if (tom instanceof Person) { console.log("Yes I am!");}因此,可以得出结论:JS对象的原型总是连接到直接的“父对象”和Object.prototype 。没有像Python或Java这样的类 。JS是由对象组成,那么什么是原型链呢?如果你注意的话,咱们提到过几次“原型链” 。JS对象可以访问代码中其他地方定义的方法,这看起来很神奇 。再次考虑下面的例子:
var Person = { name: "noname", age: 0, greet: function() { console.log(`Hello ${this.name}`); }};var Tom = Object.create(Person);Tom.greet();即使该方法不直接存在于“Tom”对象上,Tom也可以访问greet() 。
这是JS的一个内在特征,它从另一种称为Self的语言中借用了原型系统 。当访问greet()时,JS引擎会检查该方法是否可直接在Tom上使用 。如果不是,搜索将继续向上链接,直到找到该方法 。
“链”是Tom连接的原型对象的层次结构 。在我们的例子中,Tom是Person类型的对象,因此Tom的原型连接到Person.prototype 。而Person.prototype是Object类型的对象,因此共享相同的Object.prototype原型 。如果在Person.prototype上没有greet(),则搜索将继续向上链接,直到到达Object.prototype 。这就是咱们所说的“原型链” 。
保护对象不受操纵
大多数情况下,JS 对象“可扩展”是必要的,这样咱们可以向对象添加新属性 。但有些情况下,我们希望对象不受进一步操纵 。考虑一个简单的对象:
var superImportantObject = { property1: "some string", property2: "some other string"};
推荐阅读
- 在生活中感悟普洱的生命
- 楼市再迎暴击!央行摸底线上消费贷款流入楼市 这个“把炒房客逼疯”的城市或成模仿对象,深圳已复制粘贴
- 生命的亮点
- 敬你杯茶
- 请珍惜每片茶叶生命
- 茶从来不说话 生命从来不喧哗
- 厨房装修风水 充满现代感与生命力
- 在泡茶中感悟生命
- 生命的撮清茶 淡久生香
- 普洱茶 味有生命的茶