深度剖析---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

 

posted @ 2020-04-21 11:34  Action_swt  阅读(137)  评论(0编辑  收藏  举报