最近看下了方方大佬在知乎上一篇將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的理解更透徹了,開心,耶