先來(lái)看一個(gè)例子
function Person() {
this.name = 'chengxuyuan';
this.age = 26;
this.type = '人類';
this.eat = function() {
alert("吃老鼠");
};
}
var p1 = new Person();
var p2 = new Person();
通過(guò)Person創(chuàng)建了兩個(gè)對(duì)象p1 p2哄啄,里面定義的屬性方法在內(nèi)存里面是兩份。
p1.type == p2.type // false
p1.eat == p2.eat // false
在這個(gè)人類的實(shí)例中姐仅,type是'人類'這個(gè)屬性刊头,new出來(lái)的對(duì)象基本上都是這個(gè)值,
eat這個(gè)函數(shù)也是所有對(duì)象都有的行為佛舱,從業(yè)務(wù)性質(zhì)講是不變的椎例,因此就每次要每次new都占用一份內(nèi)存。
我們應(yīng)該有一種機(jī)制请祖,不論new多少次订歪,某個(gè)類某些屬性方法都共享一份,那么肆捕,前面學(xué)習(xí)的prototype就派上用場(chǎng)了~
因此正確的姿勢(shì)就是這樣:
function Person() {
this.name = 'chengxuyuan';
this.age = 26;
Person.prototype.type = '人類';
Person.prototype.eat = function () {
console.log('吃飯');
};
}
// 也可以寫在外面動(dòng)態(tài)添加原型類的屬性或者方法
Person.prototype.job = "coding";
Person.prototype.breath = function () {console.log('呼吸'); };
var p1 = new Person();
var p2 = new Person();
這樣p1 刷晋, p2 的type,job屬性,eat眼虱,breath方法喻奥,都指向同一個(gè)內(nèi)存地址。
現(xiàn)在我們可以通過(guò)這種方案隨心所欲的new出對(duì)象捏悬,實(shí)現(xiàn)js里面的面向?qū)ο蟪绦蛟O(shè)計(jì)撞蚕,但通常實(shí)際生產(chǎn)環(huán)境中,我們不經(jīng)常用new的方式創(chuàng)建對(duì)象邮破。例如React Native里面View對(duì)象的源碼(View.js) 里面:
const View = createReactClass({
displayName: 'View',
// TODO: We should probably expose the mixins, viewConfig, and statics publicly. For example,
// one of the props is of type AccessibilityComponentType. That is defined as a const[] above,
// but it is not rendered by the docs, since `statics` below is not rendered. So its Possible
// values had to be hardcoded.
mixins: [NativeMethodsMixin],
// `propTypes` should not be accessed directly on View since this wrapper only
// exists for DEV mode. However it's important for them to be declared.
// If the object passed to `createClass` specifies `propTypes`, Flow will
// create a static type from it. This property will be over-written below with
// a warn-on-use getter though.
// TODO (bvaughn) Remove the warn-on-use comment after April 1.
propTypes: ViewPropTypes,
..................
});
創(chuàng)建對(duì)象的方法是通過(guò)createReactClass({ xx:xx , yy:xx ....});方式诈豌。
下面介紹這樣的創(chuàng)建的對(duì)象姿勢(shì)
最終正確的姿勢(shì)
function Person(props) {
this.name = props.name || 'people'; // 默認(rèn)值為'匿名'
this.age = props.grade || 1; // 默認(rèn)值為1
}
Person.prototype.hello = function () {
alert('Hello, ' + this.name + '!');
};
function createPerson(props) {
return new Person(props || {})
}
var p = createPerson({
name:'hanxiaoqing'
});
這樣的creat xx函數(shù)不需要new來(lái)調(diào)用,因?yàn)橛行r(shí)候我們會(huì)忘記寫new抒和,會(huì)造成類聲明體內(nèi)部的this找不到指向的對(duì)象矫渔,為undefined,造成問(wèn)題會(huì)很嚴(yán)重摧莽。使用creat xx函數(shù)可以很好的避免這種問(wèn)題庙洼。
還有一個(gè)好處就是參數(shù)非常靈活,不傳值就是聲明時(shí)候的可定制的默認(rèn)值镊辕,如name油够,傳值就覆蓋默認(rèn)值。