深度剖析---JavaScript对象---原型,原型链。
JavaScript 引用数据类型:
对象 字面量------ {} 。
---------------------------------------------------------------------------------------------------------------------------------------------------------------
在JavaScript当中所有的变量都可以当作对象使用。(当作对象使用,意味着拥有属性和方法)---------》万物皆对象。
但是除两个例外 null 和 undefined 。
例如:
[1,2,3].toString() -------》 "1,2,3"
function Swt(){ };
Swt.name = "博客园";
Swt.name ----》 "博客园"
但是特殊的数据类型:Number的字面量
官方给出解释 Number字面量不能当作对象使用是因为JavsScript的解析器的一个错误。因为它会将点操作符解析成数字字面量的一部分。
但是 123..toString() -----或者 ----- 123 .toString() ------再或者------ (123).toString() --------------》都会正常解析。
---------------------------------------------------------------------------------------------------------------------------------------------------------------
对象作为JavaScript语言的一种引用数据类型。
他的作用超乎你的想象。
对象可以作为----哈希表----使用!!! -------因为数据格式的特殊。
对象特点保存 键于值得对象关系。
首先对象的创建方式之一:
字面量创建对象 var obj = {}; 字面量创建对象将会从Object.prototype继承下面,没有任何的自定义属性。
例如:
var swtObj = {
name:"博客园",
age:"永远" + 18,
changHandle:function(){
}
};
访问对象属性的方式:(点操作符或者中括号操作符)
1、点操作符
swtObj.name; ---------》 "博客园"
swtObj['name'; ----------》 "博客园"
-----------------------------------------------------------------
var offer = "程序员";
swtObj[offer]; ----------》 "程序员"
-----------------------------------------------------------------
swtObj.123; -----------》 报错 --- 属性名,键(key)不能为number类型
swtObj['123']; -----------》 正常解析。
两者访问对象属性都可以,但是中括号操作符功能更强一些:比如动态设置属性,属性名有效性(空格,js关键字)
删除属性的方式:
真正意义上的删除也是唯一的删除方法是使用 delete 操作符。
注意 将对象属性设置为 undefined 或者 null 并不是真正意思上的从对象上删除属性,而仅仅是断开属性和值的关联。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
对象原型:
这里需要注意的是:
JavaScript中对象的原型和原型链 与 ES6中 class类的原型和原型链的区别!!!
JavaScript中对象使用的是 ----- prototype ----- 原型模型。
官方给我出解释:
虽然这经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大。 实现传统的类继承模型是很简单,但是实现 JavaScript 中的原型继承则要困难的多。
补充:
JavaScript为何难:
原因之一是 JavaScript 是唯一一个被广泛使用的基于原型继承的语言。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
不同之处:
1、 JavaScript 使用原型链的继承方式。
由于在JavaScript当中,函数也是对象,可以永远属性,其实每一个函数都拥有一个特殊的属性叫作原型(prototype)
每一个构造函数都拥有一个prototype属性
在对象当中使用一个属性时,浏览器所有已经声明了的 __proto__
上都不存在这个属性,然后就得出结论,这个属性是 undefined
实例化对象的 __proto__
属性就是构造函数(实例化函数)属性prototype
默认情况下, 所有函数的原型属性的 __proto__
就是 window.Object.prototype
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
创建对象的方式:
1、字面量创建。
2、实例化创建。
3、使用Object.create()创建。
对象上面常用的一些方法:
1、hasOwnProperty
hasOwnProperty
是 JavaScript 中唯一一个处理属性但是不查找原型链的函数。
// 修改Object.prototype Object.prototype.bar = 1; var foo = {goo: undefined}; foo.bar; // 1 'bar' in foo; // true foo.hasOwnProperty('bar'); // false foo.hasOwnProperty('goo'); // true
JavaScript 不会保护 hasOwnProperty
被非法占用,因此如果一个对象碰巧存在这个属性, 就需要使用外部的 hasOwnProperty
函数来获取正确的结果。
var foo = { hasOwnProperty: function() { return false; }, bar: 'Here be dragons' }; foo.hasOwnProperty('bar'); // 总是返回 false // 使用其它对象的 hasOwnProperty,并将其上下文设置为foo ({}).hasOwnProperty.call(foo, 'bar'); // true
结论
当检查对象上某个属性是否存在时,hasOwnProperty
是唯一可用的方法。 同时在使用 for in
loop 遍历对象时,推荐总是使用 hasOwnProperty
方法, 这将会避免原型对象扩展带来的干扰。
for in遍历对象:
和 in
操作符一样,for in
循环同样在查找对象属性时遍历原型链上的所有属性。
// 修改 Object.prototype Object.prototype.bar = 1; var foo = {moo: 2}; for(var i in foo) { console.log(i); // 输出两个属性:bar 和 moo }
由于不可能改变 for in
自身的行为,因此有必要过滤出那些不希望出现在循环体中的属性, 这可以通过 Object.prototype
原型上的 hasOwnProperty
函数来完成。
注意: 由于 for in
总是要遍历整个原型链,因此如果一个对象的继承层次太深的话会影响性能。
使用 hasOwnProperty
过滤
// foo 变量是上例中的 for(var i in foo) { if (foo.hasOwnProperty(i)) { console.log(i); } }
这个版本的代码是唯一正确的写法。由于我们使用了 hasOwnProperty
,所以这次只输出 moo
。 如果不使用 hasOwnProperty
,则这段代码在原生对象原型(比如 Object.prototype
)被扩展时可能会出错。
一个广泛使用的类库 Prototype 就扩展了原生的 JavaScript 对象。 因此,当这个类库被包含在页面中时,不使用 hasOwnProperty
过滤的 for in
循环难免会出问题。
原文:https://bonsaiden.github.io/JavaScript-Garden/zh/#object.prototype