25.原型链和原型(非常重要),听说你还没搞懂??

1. 对原型、原型链的理解

在JavaScript中是使用构造函数来新建一个对象的每一个构造函数的内部都有一个 prototype 属性,它的属性值是一个对象,这个对象包含了可以由该构造函数的所有实例共享的属性和方法当使用构造函数新建一个对象后,在这个对象的内部将包含一个指针,这个指针指向构造函数的 prototype 属性对应的值,在 ES5 中这个指针被称为对象的原型。一般来说不应该能够获取到这个值的,但是现在浏览器中都实现了 __proto__属性来访问这个属性,但是最好不要使用这个属性,因为它不是规范中规定的。ES5 中新增了一个 Object.getPrototypeOf() 方法,可以通过这个方法来获取对象的原型。

访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是 Object.prototype 所以这就是新建的对象为什么能够使用 toString() 等方法的原因。

特点: JavaScript 对象是通过引用来传递的,创建的每个新对象实体中并没有一份属于自己的原型副本。当修改原型时,与之相关的对象也会继承这一改变。

 

 

2. 原型修改、重写

function Person(name) {
    this.name = name
}
// 修改原型
Person.prototype.getName = function() {}
var p = new Person('hello')
console.log(p.__proto__ === Person.prototype) // true
console.log(p.__proto__ === p.constructor.prototype) // true
console.log(p.__proto__);//{getName: ƒ, constructor: ƒ}
console.log(p.constructor.prototype);//{getName: ƒ, constructor: ƒ}


// 重写原型
Person.prototype = {
    getName: function() {}
}
var p = new Person('hello')
console.log(p.__proto__ === Person.prototype)        // true
console.log(p.__proto__ === p.constructor.prototype) // false
console.log(p.__proto__);//{getName: ƒ, constructor: ƒ}
console.log(p.constructor.prototype);//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}

可以看到修改原型的时候p的构造函数不是指向Person了,因为直接给Person的原型对象直接用对象赋值时,它的构造函数指向的了根构造函数Object,所以这时候p.constructor === Object ,而不是p.constructor === Person。要想成立,就要用constructor指回来:

Person.prototype = {
    getName: function() {}
}
var p = new Person('hello')
p.constructor = Person
console.log(p.__proto__ === Person.prototype)        // true
console.log(p.__proto__ === p.constructor.prototype) // true

3. 原型链指向

p.__proto__  // Person.prototype
Person.prototype.__proto__  // Object.prototype
p.__proto__.__proto__ //Object.prototype
p.__proto__.constructor.prototype.__proto__ // Object.prototype
Person.prototype.constructor.prototype.__proto__ // Object.prototype
p1.__proto__.constructor // Person
Person.prototype.constructor  // Person

 

4. 原型链的终点是什么?如何打印出原型链的终点?

由于Object是构造函数,原型链终点是Object.prototype.__proto__,而Object.prototype.__proto__=== null // true,所以,原型链的终点是null。原型链上的所有原型都是对象,所有的对象最终都是由Object构造的,而Object.prototype的下一级是Object.prototype.__proto__。 

5. 如何获得对象非原型链上的属性?

使用后hasOwnProperty()方法来判断属性是否属于原型链的属性:

function iterate(obj){
   var res=[];
   for(var key in obj){
        if(obj.hasOwnProperty(key))
           res.push(key+': '+obj[key]);
   }
   return res;
} 

相关推荐

  1. 原型原型

    2024-02-16 22:52:02       34 阅读
  2. 原型原型

    2024-02-16 22:52:02       36 阅读
  3. js 原型 原型

    2024-02-16 22:52:02       37 阅读
  4. 理解原型原型

    2024-02-16 22:52:02       8 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-16 22:52:02       17 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-16 22:52:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-16 22:52:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-16 22:52:02       18 阅读

热门阅读

  1. 15.3 OpenGL可编程片段处理:片段着色器查询

    2024-02-16 22:52:02       33 阅读
  2. 「MySQL」事务

    2024-02-16 22:52:02       31 阅读
  3. 相向双指针题单

    2024-02-16 22:52:02       36 阅读
  4. leetcode刷题记录:二叉树02(思路篇)

    2024-02-16 22:52:02       31 阅读
  5. Spring基础 - Spring和Spring框架组成

    2024-02-16 22:52:02       28 阅读
  6. C++中const关键字详解

    2024-02-16 22:52:02       26 阅读
  7. C/C++中static关键字详解

    2024-02-16 22:52:02       30 阅读
  8. CCF编程能力等级认证GESP—C++1级—20231209

    2024-02-16 22:52:02       48 阅读
  9. Vue语法

    Vue语法

    2024-02-16 22:52:02      24 阅读
  10. 【动态规划】买卖股票问题

    2024-02-16 22:52:02       30 阅读
  11. MTR++论文阅读

    2024-02-16 22:52:02       30 阅读
  12. Leetcode 647. 回文子串

    2024-02-16 22:52:02       30 阅读