对象
对象对象是已命名的数据集合。其中“已命名的数据”指的就是它的属性和方法,如:
var a = { val : 1 , func:function(){}}对象 a 拥有两个已命名的数据 val 和 func 。
访问对象的成员可以使用 . 或 [ ] ,其中 . 运算符要求它右边必须是合法的标示符,而 [ ] 运算符,对它的操作数并无要求,任何合法的值都可以,如:
a.val // 1a.func() // undefined
a["x"] = 2 // a : { val : 1 , func:function(){} , x : 2 }
a[null] = 3 // a : { val : 1 , func:function(){} , x : 2 ,null : 3}
2.原型
对象有一个私有的属性 __proto__,持有其原型的引用。
对象的原型,也是一个对象。对象与它的原型的关系就是:数据共享,这体现在对象属性值的查找过程。访问对象的属性,首先在它自定义的数据集合中寻找,找到后,立即返回该值;如果没有找到,则到它的原型中寻找,找到后,立即返回值;....;如果一直到原型链(原型还可以有原型)的末端都没有找到,则返回 undefined。
var b = { bPro : "in b" }a.__proto__ = b
alert( a.bPro ) // in b
如果一个对象没有显式的指定原型,那么它的原型默认是 Object.prototype ,而 Object.prototype.__proto__ = null ,所以它就是所有原型链的结尾。
为对象添加了一个在原型中存在的属性,则会覆盖对原型属性的访问。
a.bPro = "in a"alert(a.bPro) // "in a"
alert(a.__proto__.bPro) // "in b"
可以看到,修改对象,并未影响到原型,更不会影响到共享同一个原型的其他对象。
3. 构造函数
任何函数都可以用作构造函数,只要使用 new 运算符进行调用即可。
构造函数的原理,就是创建一个对象,并将函数的属性 prototype 赋给刚刚创创建的这个对象的 __proto__ 属性、传递原型,然后将 this 指向它;执行函数体,函数体中形如 this.x = y 的代码都是在给这个刚创建的对象添加成员;最后这个新创建的对象会作为 new 表达式的值返回。如下:
function obj(xValue){this.x = xValue
}
obj.prototype = { pro : "in prototype" }
var a = new obj(1) // { x : 1 }
alert(a.pro) // "in prototype"
a.__proto__ === obj.prototype // true
当然,函数也可以返回值。但只有 Object 类的实例(包括子类实例)才会生效,其他的值都会被忽略,继续返回刚创建的对象(即使函数体中一个 this 都么有)。
function func( ret ){this.x = 5
return ret
}
var a = new func() // { x : 5 }
var b = new func( null ) // { x : 5 }
var c = new func( { } ) // { }
var d = new func( [] ) // []
var e = new func( 1 ) // { x : 5 }
var f = new func( new Number( 1 ) ) // Number
4. Bulalalal
后面的我没看懂,查了查,发现内容也没啥新鲜的。
如果一个拥有返回值,且返回的是 Object 类的实例(包括子类实例),那么使用不使用 new 运算符的结果都是一样的。同其他语言中一样,具有这样功能函数,都叫做工厂函数,更复杂的创建过程可能不叫这个名字,但也一定会包括"工厂"二字。
function obj(x , y ){return { proX : x , proY : y }
}
虽然说懂了原理,其他的都是形式问题。但其实我也觉得有必要深入了解一下,毕竟和人交流的时候,不能让一些其实没多大意义的名词给难住、影响沟通效果。
只是我有点累了,手指头快麻了,我去瞅瞅别的东西了。(还有,我已不做程序员好多年,新东西学不动了)
参考文章:对象 http://www.tootei.net/archives/365#2-1 推荐你将函数那一章也看看。