從另一個角度思考JS中的new

最近看下了方方大佬在知乎上一篇將new的文章很有啟發(fā),沒有從面向?qū)ο蟮慕嵌热ニ伎?,但卻有著更底層的思考,我給自己總結(jié)記錄一下。

1、那個經(jīng)典的例子開始說起

首先我們創(chuàng)建一個包含人類對象,它包含一些屬性和方法

// person 對象
var person = {
  name: 'join',
  age: 12,
  say: function(){
    console.log('say')
  },
  jump: function(){
    console.log('jump')
  }
}

2、現(xiàn)在我們需要一百個這樣的person對象

下面用最笨的一個方法來實現(xiàn)以下

var  persons = []
var  person

for(var i=0; i<100; i++){
  person = {
    name: 'join',
    age: 12,
    say: function(){
      console.log('say')
    },
    jump: function(){
      console.log('jump')
    }
  }
  persons.push(pseron)
}

這樣寫看著很傻是吧,如果你對原型鏈有一個了解的話,那么這些方法可以用掛在原型鏈上,來解決重新創(chuàng)建的問題,來看一下改進(jìn)版本。

var  persons = []
var  personShare = {
  say: function(){
    console.log('say')
  },
  jump: function(){
    console.log('jump')
  }
}

for(var i=0; i<100; i++){
  person = {
    // 每個人的name和age都是不一樣的,所以寫在這里了
    name: 'join',
    age: 12,
  }
  person.__proto__ = personShare
  // __proto__是一個隱藏屬性,平時并不建議這么使用
  // person.__proto__.say = person.say = personShare.say
  // person.__proto__.jump = person.jump = personShare.jump
  
   persons.push(pseron)
}

3、優(yōu)雅的改進(jìn)一下

然后這邊可以發(fā)現(xiàn)的是不是將person分成兩部分寫起來不太優(yōu)雅,接下來在進(jìn)行一點優(yōu)雅版本的改進(jìn),用一個函數(shù)將兩部分合起來

person.prototype = {
  say: function(){
    console.log('say')
  },
  jump: function(){
    console.log('jump')
  }
}

function person(name, age) {
  //先來創(chuàng)建一個臨時對象
  var temp = {}

  // 加上屬性
  temp.name = name
  temp.age = age

  //加上方法
  temp.__proto__ =  person.prototype

  return temp
}

// 這樣看起來起來是不是就很簡潔了
var persons = []
var name = ['a','b','c', ...]
var age = [1,2,3, ...]
for(var i=0; i<100; i++){
  persons.push(person(name[i], age[i]))
}

4、new 出來啦?。。?/h4>

上面有這樣一句代碼

persons.push(person(name, age))

這里我們可以把person(name, age) 當(dāng)作new Person(name ,age)來看的話,在出來理解下是不是感覺出其的相似,就是這樣的,站在這個視角上,new 幫我們做了這幾個事情

  • 不用創(chuàng)建臨時對象,因為 new 會幫你做(你使用「this」就可以訪問到臨時對象);
  • 不用綁定原型,因為 new 會幫你做(new 為了知道原型在哪,所以指定原型的名字為 prototype);
  • 不用 return 臨時對象,因為 new 會幫你做;
  • 不要給原型想名字了,因為 new 指定名字為 prototype。

我們這一次用new來寫

function Person(name, age){
  this.age = age
  this.name = name
}
Person.prototype = {
  say: function(){
    console.log('say')
  },
  jump: function(){
    console.log('jump')
  }
}

var persons = []
for(var i=0; i<100; i++){
  persons.push(new Person(name, age))
}

我們可以從3中的代碼看到4中代碼,發(fā)現(xiàn)其實new本質(zhì)上是JS之父發(fā)明給我們的語法糖,幫我們少些一些代碼(一般new都是和構(gòu)造函數(shù)在一起的,后面的函數(shù)一般用首字母大寫用來區(qū)分和其他的普通函數(shù)的區(qū)別)

5、 constructor屬性

new 操作為了記錄「臨時對象是由哪個函數(shù)創(chuàng)建的」,會預(yù)先在person.prototype加一個constructor 屬性,

person.prototype = {
  constructor: person
}

如果我們從新對person.prototype賦值就會覆蓋掉constructor這個屬性,所以我們應(yīng)該這樣寫

person.prototype.say = function(){
  console.log('say')
}
person.prototype.jump = function(){
  console.log('jump')
}

哇,感覺自己現(xiàn)在對new的理解更透徹了,開心,耶

參考鏈接: https://zhuanlan.zhihu.com/p/23987456

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容