前后端知识交流分享前端经验分享

原型链

2019-01-07  本文已影响4人  重新改的名字

目录

  1. 创建对象有几种方法
  2. 原型、构造函数、实例、原型链
  3. instanceof的原理
  4. new运算符

创建对象的方法

在了解原型链之前,首先先了解一下创建对象的几种方式,介绍以下三种。

image

代码:

    // 第一种方式:字面量
    var o1 = {name: 'o1'} 
    var o2 = new Object({name: 'o2'}) // 第二种方式:构造函数
    var M = function (name) { this.name = name; } 
    var o3 = new M('o3') // 第三种方式:Object.create
    var p = {name: 'p'} 
    var o4 = Object.create(p)

  console.log(o1)
   console.log(o2)
  console.log(o3)
  console.log(o4)

打印结果:

image

原型及原型链

先来一张容易让人懵逼的图

image

什么是原型对象?实例?构造函数?

概念就不多说了,看代码吧

var M = function (name) { this.name = name; }
var o3 = new M('o3')

再来通过下面这个图来理解一下

image

那什么是原型链呢?

简单理解就是原型组成的链,对象的proto它的是原型,而原型也是一个对象,也有proto属性,原型的proto又是原型的原型,就这样可以一直通过proto想上找,这就是原型链,当向上找找到Object的原型的时候,这条原型链就算到头了。

原型对象和实例之间有什么作用呢?

通过一个构造函数创建出来的多个实例,如果都要添加一个方法,给每个实例去添加并不是一个明智的选择。这时就该用上原型了。

在实例的原型上添加一个方法,这个原型的所有实例便都有了这个方法。

接着上面的例子继续演示:

var M = function (name) { this.name = name; }
var o3 = new M('o3')
var o5 = new M()</pre>

o3.__proto__.say=furnction(){
   console.log('hello world')
}

o3.say()
o5.say()

打印结果

image

按照JS引擎的分析方式,在访问一个实例的属性的时候,现在实例本身中找,如果没找到就去它的原型中找,还没找到就再往上找,直到找到。这就是原型链。

补充:

只有函数有prototype,对象是没有的。

但是函数也是有proto的,因为函数也是对象。函数的proto指向的是Function.prototype。

也就是说普通函数是Function这个构造函数的一个实例。

image

instanceof原理

image

instanceof是判断实例对象的proto和生成该实例的构造函数的prototype是不是引用的同一个地址。

是返回true,否返回false。

注意:实例的instanceof在比较的时候,与原型链上想上找的的构造函数相比都是true。

继续上面的代码

image

那怎么判断实例是由哪个构造函数生成的呢?这时候就要用到constructor了。

实例的原型的构造函数, obj.proto.constructor

image

new运算符

new运算符的原理

下面根据new的工作原理通过代码手动实现一下new运算符

var new2 = 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;             //不是返回返回构造函数的执行结果
  }
} 

验证

image

经过上图一系列折腾,不难看出,我们手动编写的new2和new运算符的作用是一样的。

转载出处:https://www.cnblogs.com/chengzp/p/prototype.html

上一篇下一篇

猜你喜欢

热点阅读