JavaScript 对象(Object)学习(一)

JavaScript 中的对象实际上就是一个由属性组成的关联数组,属性由名称和值组成,值的类型可以是任何数据类型,或者函数和其他对象。
注意:JavaScript 具有函数式编程的特性,所以函数也是一种变量,大多数时候不用与一般的数据类型区分。
在 JavaScript 中,你可以用以下方法创建一个简单的对象:

	var foo = {};
	foo.prop_1 = 'bar';
	foo.prop_2 = false;
	foo.prop_3 = function() {
		return 'hello world';
	}
	console.log(foo.prop_3());

{} 是对象字面量的表示方法,也可以用 var foo = new Object() 来显式地创建一个对象。

1. 使用关联数组访问对象成员

var foo = {};
foo['prop1'] = 'bar';
foo['prop2'] = false;
foo['prop3'] = function() {
	return 'hello world';
}

在 JavaScript 中,使用句点运算符和关联数组引用是等价的,也就是说任何对象(包括this 指针)都可以使用这两种模式。使用关联数组的好处是,在我们不知道对象的属性名称的时候,可以用变量来作为关联数组的索引。例如:

var some_prop = 'prop2';
foo[some_prop] = false;

2. 使用对象初始化器创建对象

var foo = {
    'prop1': 'bar',
	prop2: 'false',
	prop3: function (){
		return 'hello world';
	}
};

这种定义的方法称为对象的初始化器。注意,使用初始化器时,对象属性名称是否加引号是可选的,非属性名称中有空格或者其他可能造成歧义的字符, 否则没有必要使用引号。

3、构造函数
我们想创建多个规划好的对象,有若干个固定的属性、方法,并能够初始化,JavaScript 提供了构造函数,让我们来看看应该如何
创建复杂的对象。

function User(name, uri) {
	this.name = name;
	this.uri = uri;
	this.display = function() {
		console.log(this.name);
	}
}
var someuser = new User('byvoid', 'http://www.byvoid.com');
console.log(someuser.uri);

4、上下文对象
在 JavaScript 中,上下文对象就是 this 指针,即被调用函数所处的环境。上下文对象的作用是在一个函数内部引用调用它的对象本身,JavaScript 的任何函数都是被某个对象调用的,包括全局对象,所以 this 指针是一个非常重要的东西。

var someuser = {
	name: 'byvoid',
	display: function() {
		console.log(this.name);
	}
};
someuser.display(); // 输出 byvoid

var foo = {
	bar: someuser.display,
	name: 'foobar'
};
foo.bar(); // 输出 foobar

Javascript的prototype与constructor

当Javascript创建一个函数的时候,会同时创建一个原型对象,赋值到函数的prototype属性,作为使用new生成实例对象的默认原型对象。

该默认原型对象的内容是:
{
__proto__:Object.prototype,
constructor: 指向函数本身
}

__proto__指向Object.prototype的目的是为了使生成的实例对象继承顶层对象Object.prototype;

原型对象中constructor指向构造函数本身。目的是为了使生成的实例对象newObject可以直接通过newObject.constructor访问到构造函数。

同时构造函数和原型对象可以互相访问也是个良好的设计。

构造函数,原型对象,实例对象的三角关系图如下:

构造函数-原型对象-实例对象的三角关系图

实例:

var A = function (){};  
var a = new A();  
console.log(a.constructor) // 此时输出的就是A的函数体,即function(){}
console.log(a.constructor === A);  //true 

实例a的constructor就是指向A。
而A.prototype.constructor又是指向谁呢?这个不难判断,因为实例a.constructor默认就是指向A.prototype.constructor,即

console.log(a.constructor === A.prototype.constructor); //true  
console.log(A.prototype.constructor === A);//true  

参考:
http://12d.iteye.com/blog/1560697
http://www.iteye.com/topic/1126635

使用对象字面量语法构造函数两种方法区别

function myConstructor(){
  //私有和特权成员
}
或者,
var myConstructor = function(){
  //私有和特权成员
}

浏览器中的解释程序在执行javascript代码之前,首先要对代码进行变量初始化,即初始化window对象之下的所有顶级变量。

由于第2种定义函数的语法是通过赋值语句实现的,所以在初始化过程中不会被立即声明。

只有在解释器开始执行代码并执行到相应的赋值语句时,该函数才会被声明。因此调用该函数的语句只能出现在定义该函数之后。并且,如果使用第2种方法来定义构造函数,那么为其prototype属性中添加公共成员的代码。也应该放在该函数定义之后。

比如function example(){…}时,example()函数会在脚本之前立即被声明。这意味着你可以在脚本中任何地方调用example(),即使对函数的调用发生在函数的定义之前也没有问题。而对于第2种替代语法来说,如var example2 = function(){…},在脚本执行到赋值语句之前example2()函数是不存在的。如果你在该定义发生之前调用example2(),结果会失败。