問(wèn):在js里面被<code>new</code>之后的函數(shù)和普通的函數(shù)有何區(qū)別嗎?
1. New命令#
1.1 基本用法
<code>new</code>命令的作用,就是執(zhí)行<code>構(gòu)造函數(shù)</code>,返回一個(gè)<code>實(shí)例對(duì)象</code>。
var Person = function(name){
this.name = name;
}
var p1 = new Person("張三");
var p2 = new Person("李四");
//p1和p2都是Person這個(gè)類(構(gòu)造函數(shù))的實(shí)例
p1.name//張三
p2.name//李
如果不用<code>new</code>將函數(shù)賦值給一個(gè)變量掷空,會(huì)如何呢?
var Person = function(name){
this.name = name;
}
var p1 = Person("張三");
p1//undefined
name//張三
var p2 = Person("李四");
p2//unddefined
name//李四
var Animate = function(type){
'use strict';
this.type = type
}
var dog = new Animate("dog");
//TypeError: Cannot set property 'type ' of undefined
//因?yàn)?use strict 是嚴(yán)格模式
上面代碼分別調(diào)用兩次<code>Person</code>函數(shù)囤锉,但由于<code>Person</code>函數(shù)沒(méi)有返回值坦弟,所以,<code>p1,p2</code>都為<code>undefined</code>官地。<code>this</code>表示當(dāng)前作用域酿傍,由于沒(méi)有<code>new</code>,當(dāng)前的作用域仍然是全局的。所以驱入,最后<code>name</code>為"李四"
1.2 new原理
創(chuàng)建一個(gè)空對(duì)象赤炒,作為將要返回的對(duì)象實(shí)例
將這個(gè)空對(duì)象的原型,指向構(gòu)造函數(shù)的<code>prototype</code>屬性
將這個(gè)空對(duì)象賦值給函數(shù)內(nèi)部的<code>this</code>關(guān)鍵字
開(kāi)始執(zhí)行構(gòu)造函數(shù)內(nèi)部的代碼
如果構(gòu)造函數(shù)內(nèi)部有<code>return</code>語(yǔ)句亏较,而且<code>return</code>后面跟著一個(gè)對(duì)象莺褒,<code>new</code>命令會(huì)返回<code>return</code>語(yǔ)句指定的對(duì)象;否則雪情,就會(huì)不管<code>return</code>語(yǔ)句遵岩,返回<code>this</code>對(duì)象
var Vehicle = function () {
this.price = 1000;
return 1000;
};
(new Vehicle()) === 1000
//上面代碼中,構(gòu)造函數(shù)Vehicle的return語(yǔ)句返回一個(gè)數(shù)值巡通。
//這時(shí)尘执,new命令就會(huì)忽略這個(gè)return語(yǔ)句,返回“構(gòu)造”后的this對(duì)象
但是扁达,如果<code>return</code>語(yǔ)句返回的是一個(gè)跟<code>this</code>無(wú)關(guān)的新對(duì)象正卧,<code>new</code>命令會(huì)返回這個(gè)新對(duì)象蠢熄,而不是<code>this</code>對(duì)象跪解。這一點(diǎn)需要特別引起注意。
var Vehicle = function (){
this.price = 1000;
return { price: 2000 };
};
(new Vehicle()).price// 2000
另一方面,如果對(duì)普通函數(shù)(內(nèi)部沒(méi)有<code>this</code>關(guān)鍵字的函數(shù))使用<code>new</code>命令叉讥,則會(huì)返回一個(gè)空對(duì)象窘行。
function getMessage() {
return 'this is a message';
}
var msg = new getMessage();
msg // {}
typeof msg // "Object"
<code>new</code>命令簡(jiǎn)化的流程
function Persion(name){
this.name = name;
}
function _new(/* 構(gòu)造函數(shù) */ constructor, /* 構(gòu)造函數(shù)參數(shù) */ param1) {
// 將 arguments 對(duì)象轉(zhuǎn)為數(shù)組
var args = [].slice.call(arguments);
// 取出構(gòu)造函數(shù)
var constructor = args.shift();
// 創(chuàng)建一個(gè)空對(duì)象,繼承構(gòu)造函數(shù)的 prototype 屬性
var context = Object.create(constructor.prototype);
// 執(zhí)行構(gòu)造函數(shù)
var result = constructor.apply(context, args);
// 如果返回結(jié)果是對(duì)象图仓,就直接返回罐盔,則返回 context 對(duì)象
return (typeof result === 'object' && result != null) ? result : context;
}
var p = _new(Persion, "xxx");
console.info(p.name); //xxx
2. Object對(duì)象與繼承#
2.1 Object.getOwnPropertyNames()
<code>Object.getOwnPropertyNames</code>方法返回一個(gè)數(shù)組,成員是對(duì)象本身的所有屬性的鍵名救崔,不包含繼承的屬性鍵名惶看。
Object.getOwnPropertyNames(Date);
//["length", "name", "arguments", "caller", "prototype", "now", "parse", "UTC"]
var a = {};
Object.getOwnPropertyNames(a);
//[]
2.2 Object.prototype.hasOwnProperty()
對(duì)象實(shí)例的<code>hasOwnProperty</code>方法返回一個(gè)布爾值,用于判斷某個(gè)屬性定義在對(duì)象自身六孵,還是定義在原型鏈上
Date.hasOwnProperty('length')// true
Date.hasOwnProperty('toString')// false
2.3 in 運(yùn)算符和 for…in 循環(huán)
in運(yùn)算符返回一個(gè)布爾值纬黎,表示一個(gè)對(duì)象是否具有某個(gè)屬性颓鲜。它不區(qū)分該屬性是對(duì)象自身的屬性沮明,還是繼承的屬性。
'length' in Date // true
'toString' in Date // true