原型链

作者: 翔阿翔阿翔 | 来源:发表于2019-01-31 13:54 被阅读0次

对象的创建方法

//第一种
// 创建对象的三种方法
    let o1 = {
      name: "德玛西亚"
    }
    let o11 = new Object({
      name: "诺克萨斯"
    })
//第二种
    let M = function(name) {
      this.name = name
    }
    let o2 = new M("艾欧尼亚")
//第三种    
    let p = {
      name: '班德尔城'
    }
    let o3 = Object.create(p)
    console.log(o1)
    console.log(o11)
    console.log(o2)
    console.log(o3)

输出的结果为


输出结果

可以看到第三种只输出了一个空对象,原因后面补上。

原型,构造函数,实例,原型链

首先我们来看看一张图,这是慕课上一位老师讲解原型链时用到的图片。


原型链

构造函数

任何被 new引用到的函数都可以叫做构造函数

let M = function(name) {
  this.name = name
}
let m = new M('nimeia')
//上面的m是用new创建出来的,new引用了M(),所以M()就是一个构造函数

原型对象

当一个构造函数被new所引用的时候,js引擎会创建一个原型对象。为构造函数加上一个prototype属性,这个属性指向的就是原型对象。

实例

实例就是构造函数创建出来的对象。

let M = function() {
  console.log('demo')
}
console.log(M.prototype)
//输出
//{
//  constructor: ƒ (name)
//__proto__: Object
//}
//上面就是一个原型对象,constructor是构造器,返回构造函数
console.log(M.prototype.constructor === M) //输出为true
let m = new M()
console.log(m.__proto__ === M.prototype) //输出 true

原型链

原型链就是从实例对象往上找创建实例的原型对象,原型对象又继续往上找创建该原型对象的原型对象,直到找到object.prototype为止。这就是原型链。如果我们修改原型对象的时候,所有该原型对象创建出来的实例都可以公用这些新属性。

let M = function(name) {
  this.name = name
}
let o1 = M('你妹啊')
M.prototype.say = function () {
  console.log(this.name)
}
let o2 = new ('你大爷')
console.log(o1.say()) //输出   你妹啊
console.log(o2.say())//输出    你大爷

ps:函数也是对象

console.log(M.__proto__ === Function.prototype) //输出true

instanceof

判断实例对象的proto属性跟构造函数的prototype属性是否引用同一个地址。但是又一个问题就是在同一条原型链上的构造函数都可以被instanceof看做实例对象的一个实例,这样就不严谨。

let M = function() {}
let m = new M()
console.log(m instanceof M) //输出true
console.log(m instanceof object) //输出也是true
//这是因为
m.__proto__ === M.prototype //true
M.prototype.__proto__ === Object.prototype //true
//所以m跟object在同一条原型链上,Object被instanceof也看做m的构造函数

所以要找实例的构造函数,可以通过m.__proto__.constructor来判断

new运算符原理

  • 一个新对象被创建。它继承自foo.prototype。
  • 构造函数返回一个对象。在执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新的实例。new foo等同于new foo(), 只能用在不传递任何参数的情况
  • 如果构造函数反悔了一个对象,那个这个对象会取代整个new出来的结果。如果构造函数没有返回对象,那个new出来的结果为步骤1创建的对象。
//模拟new运算符的操作
var new = function (func) {
    var o = Object.create(func.prototype);    //创建对象
    var k = func.call(o);             //改变this指向,把结果付给k
    if (typeof k === 'object') {         //判断k的类型是不是对象
        return k;                  //是,返回k
    } else {
        return o;                  //不是返回返回构造函数的执行结果
    }
}
//验证
let m = new(M)
console.log(m instanceof M) //true
console.log(m instanceof Object) //true
console.log(m.__proto__.constructor === M) //true
M.prototype.say = function() {
  console.log('hello')
}
console.log(m.say()) //hello

上面还遗留了一个问题

就是为啥

let p = {
  name: '你妹啊'
}
let o1 = Object.create(p)
console.log(o1)

输出的是一个空对象的问题。
因为用object.create创建的对象都是对原型的引用。

consolo.log(o1.__proto__ === p) //输出true

以上就是我对原型链做出的一些理解和总结,希望对你们有帮助。帮点个喜欢吧~~~

相关文章

  • JavaScript 原型、原型链与原型继承

    原型,原型链与原型继承 用自己的方式理解原型,原型链和原型继承 javascript——原型与原型链 JavaSc...

  • 原型、原型链

    (什么是原型、原型链?有什么作用) JavaScirpt深入之从原型到原型链 图解 Javascript 原型链 ...

  • 原型链&查找规则&作用域链

    原型链(隐式原型链) 属性的查找规则(原型链的查找规则) 作用域链

  • 关于原型原型链的理解

    什么是原型? 什么是原型链? 为什么需要原型,和原型链?

  • 原型链实现继承

    原型链 原型链示意图 使用原型链实现继承 这是怎么回事呢? 原型链在哪? 听我细细道来~ 首先 Teacher 实...

  • 继承

    原型链直接继承 原型链直接继承prototype 原型链继承_prototype属性 继承_构造函数绑定

  • js中的实现继承的几种方式

    大纲:原型链借用构造函数组合继承原型式继承寄生式继承寄生组合式继承 1、原型链: 什么是原型链? 原型链的基本思想...

  • 【原型和原型链】什么是原型和原型链

    【原型和原型链】什么是原型和原型链https://blog.csdn.net/xiaoermingn/articl...

  • js原型链

    目录 1.对象的原型和原型链1.1什么是原型1.2查看原型1.3对象的原型链 2.使用构造函数2.1 函数的原型链...

  • 廖雪峰JS小记

    (function(){})() 原型,原型链 浅谈Js原型的理解JS 原型与原型链终极详解 对象 对象:一种无序...

网友评论

      本文标题:原型链

      本文链接:https://www.haomeiwen.com/subject/egdksqtx.html