首页 > 代码库 > JavaScript - 理解原型

JavaScript - 理解原型

Function对象特有的属性 prototype

所有对象都有的属性 __proto__

 

1、用法

const F = function (name) {
  this.name = name  
}
F.prototype.greeting = function () {
  console.log(‘hello‘, this.name)
}

let f1 = new F(‘osyo‘)
let f2 = new F(‘mioco‘)

f1.greeting() // hello osyo
f2.greeting() // hello mioco

可以看出,prototype主要用来放共有的属性和方法,这样你就不用每次new的时候都实例化那个属性了。

 

2、prototype和__proto__的关系

方法对象都有这两个属性,prototype是该方法的原型,__proto__是它父亲的原型(Object作为生命的起源它的__proto__为null)

 

3、应用举例

1) underscore.js代码节选

  // Save bytes in the minified (but not gzipped) version:
  var ArrayProto = Array.prototype, ObjProto = Object.prototype;
  var SymbolProto = typeof Symbol !== ‘undefined‘ ? Symbol.prototype : null;

  // Create quick reference variables for speed access to core prototypes.
  var push = ArrayProto.push,
      slice = ArrayProto.slice,
      toString = ObjProto.toString,
      hasOwnProperty = ObjProto.hasOwnProperty;

 underscore在这里把原生对象的原型保存在变量中以加快访问速度,因为原型链的索引是当前对象->对象原型->父亲的原型->...->Object原型,顺着链子往上找还是挺耗时的大约...(话说这个例子感觉用来举例原型链比较合适的样子...)

 

2) classes polyfill

我们知道ES6中新增了一个语法糖Class

ES6:

class F {
  constructor (name) {
    this.name = name
  }
  greet () {
    console.log(‘hello ‘ + this.name)
  }
}

class SubF extends F{
  constructor () {
    super(‘osyo from subF‘)
  }
  subGreet () {
    super.greet()
  }
}

let f = new SubF()
f.subGreet() //hello osyo from subF

等价于ES5:

function F (name) {
  this.name = name
}
F5.prototype.greet = function () {
  console.log(‘hello ‘ + this.name)
}
F5.greetAll = function () {
  console.log(‘hello everybody‘)
}

function SubF () {
  F.call(this, ‘osyo from subF‘)
}

// 继承属性 SubF.prototype
= Object.create(F.prototype) SubF.prototype.contructor = F SubF.greetAll = F.greetAll

//子类方法的属性 SubF.prototype.subGreet
= function () { F5.prototype.greet.call(this) }
let f
= new SubF5() f.subGreet() //hello osyo from subF

 

JavaScript - 理解原型