JS 对象的 “深入“剖析

362 阅读2分钟

借鉴文章

一起探讨 JavaScript 的对象

JS数据类型分类和判断

概念

对象是多个属性的动态集合,它有一个链接着原型的隐藏属性(注:proto)。

一个属性拥有一个 key 和一个 value 。

属性Key

  1. 点表示法, Object.name 属性key必须为有效的标识符
  2. 括号表示法, Object[ 'str' ] 属性key任意值

当属性key为非字符串时,系统将调用 toString() 方法将它转为字符串

   let obj = {};
   //Number
   obj[1] = "Number 1";
   obj[1] === obj["1"];     //true ,将 1 转化为 "1"
   
   //Object
   let number1 = {
     toString : function() { return "1"; }
   }
   obj[number1] === obj["1"]; //true, number1 运行 toString 函数

原型

对象有一个链接着原型对象的“隐藏”属性 __proto__,对象是从这个原型对象中继承属性的。

举个例子,使用对象字面量创建的对象有一个指向 Object.prototype 的链接:

   var obj = {};
   obj.__proto__ === Object.prototype; //true
   

原型链

Object.create Object.assign()理解有帮助

原型对象有它自己的原型。当一个属性被访问的时候并且不包含在当前对象中,JavaScript会沿着原型链向下查找直到找到被访问的属性,或者到达 null 为止。

   let obj = {
       name :'Rainy'
   } ;
   let son = Object.create(obj) ; //Object.create():将创建对象当做新对象的 __proto__
   
  
   son.age  = 19 ;
   
   son == 
   
   age: 19
   __proto__:
       name: "Rainy"
       __proto__: Object
       
   consoloe.log(son.name)  // Rainy , 第一步寻找 与age同级的 name,没找到,继续沿着原型链寻,第二步 找到 name
   
   

空对象

   let obj = {} ;  //不为空对象,还隐藏属性: __proto__
   
   //创建空对象
   
   let obj = Object.create( null ) ;

不可变对象

Object.freeze() 冻结一个对象。属性不能被添加、删除、更改。对象会变成不可变的。

    let book = Object.freeze({
        name: 'cc'
    })
    
    book.name = 'aa' ; //Cannot assign to read only property 'name'

判断是否为对象

typeof

typeof返回一个表示数据类型的字符串,返回结果包括:number、string、boolean、object、undefined、function。typeof可以对基本类型number、string  、boolean、undefined做出准确的判断(null除外,typeof null===“object”,这是由于历史的原因,😢);而对于引用类型,除了function之外返回的都是object。但当我们需要知道某个对象的具体类型时,typeof就显得有些力不从心了。

    typeof 1; // number 有效
    typeof ‘ ’;//string 有效
    typeof true;//boolean 有效
    typeof undefined;//undefined 有效
    typeof null;//object 无效
    typeof new Function();// function 有效
    typeof [] ;           //object 无效
    typeof new Date();     //object 无效
    typeof new RegExp();   //object 无效

instanceof

当我们需要知道某个对象的具体类型时,可以用运算符 instanceof,instanceof操作符判断左操作数对象的原型链上是否有右边这个构造函数的prototype属性,也就是说指定对象是否是某个构造函数的实例,最后返回布尔值。 检测的我们用一段伪代码来模拟instanceof内部执行过程:

注意: instanceof运算符只能用于对象,不适用原始类型的值

    [] instanceof Object  // true
    [] instanceof Array  // true
    
    原因:  数组含有多条原型链,如下图