`
Clayz
  • 浏览: 293577 次
  • 性别: Icon_minigender_1
  • 来自: 东京
社区版块
存档分类
最新评论

JavaScript语言精粹读书笔记

 
阅读更多

部分例子摘自《JavaScript语言精粹》

 

JavaScript的简单类型包括数字,字符串,布尔值,null值和undefined值,其他所有的值都是对象。数字,字符串,布尔值貌似对象,因为他们拥有方法,但他们是不可变的。JavaScript中的对象是可变的键控集合。对象通过引用来传递,他们永远不会被拷贝。

 

对象字面量

对象字面量就是包围在一对花括号中的零或多个“名/值”对。对象字面量可以出现在任何允许表达式出现的地方。所有通过对象字面量创建的对象都连接到Object.prototype这个JavaScript中标准的对象。

var stooge = {
	first_name: "Clay",
	last_name: "Zhong"
};

 

对象检索

如果尝试检索一个并不存在的成员元素的值,将返回一个undefined值:

stooge["middle_name"] //undefined
stooge.middle_name     //undefined

 

此时可用||运算符来填充默认值:

var middle_name = stooge["middle_name"] || "none";
var middle_name = stooge.middle_name || "unknown";

 

尝试检索一个undefined的属性值将会导致TypeError,这可以通过&&运算符来避免:

stooge.film                                   //undefined
stooge.film.name                         //throw TypeError
stooge.film && stooge.film.name //undefined

 

在JavaScript中函数也是对象,函数对象连接到Function.prototype(该原型对象本身连接到Object.prototype)。函数对象也可以被定义在其他函数中。函数对象可以通过函数字面量来创建:

var add = function(a, b) {
	return a + b;
}

 

函数调用

在JavaScript中一共有四种调用模式:方法调用模式,函数调用模式,构造器调用模式和apply调用模式。

 

方法调用模式:

当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this被绑定到该对象。

var myObject = {
	value: 0;
	increment: function(inc) {
		this.value += typeof inc === 'number' ? inc : 1;
	}
}

myObject.increment();
document.writeln(myObject.value);

 

函数调用模式:

当一个函数并非一个对象的属性时,那么它被当作一个函数来调用。

var sum = add(3, 4);

 

构造器调用模式:

如果在一个函数前面带上new来调用,那么将创建一个隐藏链接到该函数的prototype成员的新对象,同时this将会被绑定到那个新对象上。

//创建一个名为Quo的构造函数,它构造一个带有status属性的对象
var Quo = function(string) {
	this.status = string;
};
//给Quo的所有实例提供一个名为get_status的公共方法
Quo.prototype.get_status = function() {
	return this.status;
}
//构造一个Quo实例
var myQuo = new Quo("confused");
document.writeln(myQuo.get_status());

 

Apply调用模式:

apply方法让我们构建一个参数数组并用其去调用函数,它也允许我们选择this的值。apply方法接收两个参数,第一个是将被绑定给this的值,第二个就是一个参数数组。

var array = [3, 4];
var sum = add.apply(null, array);

 

闭包

和前面的以对象字面量形式去初始化myObject不同,我们通过调用一个函数的形式去初始化myObject,该函数将返回一个对象字面量。此函数定义了一个value变量,该变量对increment和getValue方法总是可用的,但函数的作用域使得它对其他程序来说是不可见的。

var myObject = function() {
	var value = 0;
	return {
		increment: function(inc) {
			value += typeof inc === 'number' ? inc : 1;
		},
		getValue: function() {
			return value;
		}
	}
}();
 

前面的Quo构造器产生出带有status属性和get_status方法的一个对象。但为什么要用一个getter方法去访问你本可以直接访问到的属性呢?如果status是私有属性时,它才更有意义。所以,让我们定义另一种形式的quo函数来做此事:

var quo = function(status) {
	return {
		get_status: function() {
			return status;
		}
	}
}

var myQuo = quo("amazed");
document.writeln(myQuo.get_status());

 

继承

伪类,基于new操作符的构造器调用继承,应避免使用此模式。

var Father = function(name) {
	this.name = name;
};
Father.prototype.getName = function() {
	return this.name;
}

var Son = function(age) {
	this.age = age;
}
Son.prototype.getAge = function() {
	return this.age;
}

Son.prototype = new Father("father");
document.writeln(new Son(12).getName());

 

伪类模式本意是想向面向对象靠拢,但它看起来格格不入。我们可以隐藏一些丑陋的细节,这是通过使用method方法定义一个inherits方法来实现的:

Function.method("inherits", function(Parent) {
	this.prototype = new Parent();
	return this;
});

var Son = function(age) {
	this.age = age;
}.inherits(Father).method("getAge", function() {
	return this.age;
});

 

原型

基于原型的继承相比于基于类的继承在概念上更为简单:一个新对象可以继承一个旧对象的属性。

if (typeof Object.beget !== "function") {
	Object.beget = function(o) {
		var F = function() {};
		F.prototype = o;
		return new F();
	}
}

var father = {
	name: "father",
	getName: function() {
		return this.name;
	}
}
var son = Object.beget(father);
alert(son.getName());
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics