1. 程式人生 > 實用技巧 >例項物件與new命令

例項物件與new命令

最近學習:例項物件與new命令

JavaScript語言的物件體系,是基於建構函式(constructor)和原型鏈(prototype)。
建構函式就是一個普通的函式,但有自己的特徵和用法。建構函式名字的第一個字母通常大寫。

var Vehicle = function () {
this.price = 1000;
};

建構函式特點:
1、函式體內部使用了this
2、生成物件的時候,必須使用new命令

//-------------------------------------------
var Vehicle = function () {
this.price = 1000;
};
var v = new
Vehicle(); v.price // 1000 //------------------------------------------- var Vehicle = function (p) { this.price = p; }; var v = new Vehicle(500); //-------------------------------------------

為了保證建構函式必須與new命令一起使用,

一個解決辦法是,建構函式內部使用嚴格模式,即第一行加上'use strict';
這樣的話,一旦忘了使用new命令,直接呼叫建構函式就會報錯。

function Fubar(foo, bar){
'use strict'; this._foo = foo; this._bar = bar; } Fubar() // TypeError: Cannot set property '_foo' of undefined

另一個解決辦法,建構函式內部判斷是否使用new命令,如果發現沒有使用,則直接返回一個例項物件。

function Fubar(foo, bar) {
if (!(this instanceof Fubar)) {
return new Fubar(foo, bar);
}
this._foo = foo;
this._bar = bar;
}
Fubar(1, 2)._foo //
1 (new Fubar(1, 2))._foo // 1

注:getMessage是一個普通函式,返回一個字串。對它使用new命令,會得到一個空物件。

function getMessage() {
return 'this is a message';
}
var msg = new getMessage();
msg // {}
typeof msg // "object"

構造原理:new命令簡化的內部流程,可以用下面的程式碼表示。

function _new(/* 建構函式 */ constructor, /* 建構函式引數 */ params) {
// 將 arguments 物件轉為陣列
var args = [].slice.call(arguments);
// 取出建構函式
var constructor = args.shift();
// 建立一個空物件,繼承建構函式的 prototype 屬性
var context = Object.create(constructor.prototype);
// 執行建構函式
var result = constructor.apply(context, args);
// 如果返回結果是物件,就直接返回,否則返回 context 物件
return (typeof result === 'object' && result != null) ? result : context;
}
// 例項
var actor = _new(Person, '張三', 28);

new.target
函式內部可以使用new.target屬性。如果當前函式是new命令呼叫,new.target指向當前函式,否則為undefined。

function f() {
console.log(new.target === f);
}
f() // false
new f() // true
使用這個屬性,可以判斷函式呼叫的時候,是否使用new命令。
function f() {
if (!new.target) {
throw new Error('請使用 new 命令呼叫!');
}
// ...
}
f() // Uncaught Error: 請使用 new 命令呼叫!

Object.create() 建立例項物件
建構函式作為模板,可以生成例項物件。但是,有時拿不到建構函式,只能拿到一個現有的物件。我們希望以這個現有的物件作為模板,生成新的例項物件,這時就可以使用Object.create()方法。

var person1 = {
name: '張三',
age: 38,
greeting: function() {
console.log('Hi! I\'m ' + this.name + '.');
}
};
var person2 = Object.create(person1);
person2.name // 張三
person2.greeting() // Hi! I'm 張三.

上面程式碼中,物件person1是person2的模板,後者繼承了前者的屬性和方法。