JavaScriptにおける名前付き関数の複数の呼び出し方式(2)

2439 ワード

関数にthisがあるかどうかで議論します.thisがない場合は空のオブジェクト{}を返し、thisがある場合は空でないオブジェクトを返します.
次はthisのない関数です
//         
function fun() {
	return "jack";
}

var c = new fun();
for (var atr in c) {
	alert(atr);
} 
alert(c); //[object Object]

戻り値cは「jack」ではなく、for in実行後に出力されなかった属性から、cが空のオブジェクト{}であることがわかります.thisの関数があるのを見てみましょう.関数にthisがあるのは実際にクラスを書いています.しかしjsの柔軟性のため、多くの奇妙な書き方をもたらした.
//         
function fun() {
	this.name = "tom";
	return "jack";
}

var c = new fun();
for (var atr in c) {
	alert(atr); //name
} 
alert(c.name); //tom

戻り値も「jack」ではなく、for inはname属性を出力し、最後の文はtomを出力し、戻り値cが空でないオブジェクトであることを示す.ここのreturn「jack」はまったく役に立たなかった.したがって、関数の戻り値が組み込みタイプ(基本タイプ)の場合、new方式で関数を呼び出すとエラーの結果になります.では、関数の戻り値がオブジェクト、配列、関数ですか?
//   this,        
function fun() {
	//      
	var obj = {};
	obj.name = 'andy';
	obj.age = 20;
	obj.msg = function(){}	
	return obj;
}

var c = new fun();
for (var atr in c) {
	alert(atr); //name,age,msg
} 
alert(c.name); //andy
//  this,        
function fun() {
	this.sex = "man";
	//      
	var obj = {};
	obj.name = 'andy';
	obj.age = 20;
	obj.msg = function(){}	
	return obj;
}

var c = new fun();
for (var atr in c) {
	alert(atr); //name,age,msg
} 
alert(c.name); //andy

2つのセグメントの出力結果は同じであり,cはいずれもsex属性ではなくname,age,msg属性を含む.戻り値がオブジェクトタイプ(オブジェクト、配列、関数)の場合、newはthisでオブジェクトを構築せず、組み立てられたオブジェクトを直接返す方法を説明します.この方法は実際にはファクトリ方式で、アプリケーションの多くのプログラマーが関数名の頭文字を大文字にしてクラスのように見えます.
/**
 *       Car
 */
function Car(color,doors) {	
	var car = {};
	car.color = color;
	car.doors = doors;
	car.msg = function(){ 
		alert("This is a " + this.color + " car, there are " + this.doors + " doors." );
	}	
	return car;
}

関数Carを定義し、関数内に空のオブジェクトを作成し、いくつかの属性とメソッドを追加して返します.以下に2つの作成方法を示します.
//   1
var c1 = Car('red',2);
c1.msg();

//   2
var c2 = new Car('black',4);
c2.msg();

方式1は関数呼び出し,方式2はnewである.方式2はCarをクラスと見なしているが,実際にはそうではない(Carのthisもprototypeも属性を掛けていない,方法)