JS对象分类

94 阅读4分钟

new 操作符

案例对比

1.png

总结

new X() 自动做了四件事情

  • 自动创建空对象

  • 自动为空对象关联原型,原型地址指定为 X.prototype

  • 自动将空对象作为 this 关键字运行构造函数

  • 自动 return this

构造函数 X

  • X 函数本身负责给对象本身添加属性

  • X.prototype 对象负责保存对象的共用属性

代码规范

大小写

  • 所有构造函数(专门用于创建对象的函数)首字母大写

  • 所有被构造出来的对象,首字母小写

词性

  • new 后面的函数,使用名词形式

  • 如 new Person()、new Object()

  • 其他函数,一般使用动词开头

  • 如 createSquare(5)、createElement('div')

确定一个对象的原型

  • let obj = new Object() 的原型是 Object.prototype

  • let arr = new Array() 的原型是 Array.prototype

  • let square = new Square() 的原型是 Square.prototype

  • let fn = new Function() 的原型是 Function.prototype

结论

  • 你是谁构造的 · 你的原型就是谁的 prototype 属性 · 对应的对象

原型公式

  • 对象._ _ proto _ _ === 其构造函数.prototype

类型&类

类型

  • 类型是 JS 数据的分类,有 7 种

  • 四基两空一对象

  • 类是针对于对象的分类,有无数种

  • 常见的有 Array、Function、Date、RegExp 等

数组对象

定义一个数组

  • let arr = [1,2,3]

  • let arr = new Array(1,2,3) // 元素为 1,2,3

  • let arr = new Array(3) // 长度为 3

数组对象的自身属性

  • '0' / '1' / '2' / 'length'

  • 注意,属性名没有数字,只有字符串

数组对象的共用属性

  • 'push' / 'pop' / 'shift' / 'unshift' / 'join'

  • push()  方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。

  • pop()  方法从数组中删除最后一个元素,并返回该元素的值。此方法会更改数组的长度。

  • shift()  方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

  • unshift()  方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组 )

  • join()  方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。

函数对象

定义一个函数

  • function fn(x,y){return x+y}

  • let fn2 = function fn(x,y){return x+y}

  • let fn = (x,y) => x+y

  • let fn = new Function('x','y', 'return x+y')

函数对象自身属性

  • 'name' / 'length'

函数对象共用属性

'call' / 'apply' / 'bind'

问:

window 是谁构造的

  • Window

  • 可以通过 constructor 属性看出构造者

window.Object 是谁构造的

  • window.Function

  • 因为所有函数都是 window.Function 构造的

window.Function 是谁构造的

  • window.Function

  • 因为所有函数都是 window.Function 构造的

  • 浏览器构造了 Function,然后指定它的构造者是自己

知识点

  1. JS 构造对象目前有两种方式,一种是用构造函数+prototype,一种是用 class。

  2. 关于「原型」,正确的是(多选)下文中的 x 均代表普通对象。

  • 「x 的原型」等价于「x.proto 所指的对象」 ,有时为了方便,我们可以认为「x 的原型」等价于「x.proto

  • 一个对象的原型指的是这个对象与其他同类对象的公有属性的集合,比如 obj1 和 ob2 同时拥有 toString / valueOf,那么 toString / valueOf 等属性组成的对象,就是 obj1 和 obj2 的原型,这个原型的地址一般储存在构造函数的 prototype 里

  • x.__proto__和 Object.prototype 存储着同一个对象的地址,这个对象就是 x 的原型

  • 每个对象都有原型,但除了「根对象 Object.prototype」比较特殊,Object.prototype 这个对象的原型为空 null

  1. 关于 prototype 属性,正确的有
  • 所有函数一出生就有一个 prototype 属性(除了箭头函数)

  • 所有 prototype 一出生就有一个 constructor 属性

  • 如果一个函数不是构造函数,它依然拥有 prototype 属性,只不过这个属性暂时没什么用

  • 如果一个对象不是函数,那么这个对象一般来说没有 prototype 属性,但这个对象一般一定会有 proto 属性

  1. 关于 Object.prototype,正确的是
  • Object.prototye 是「Object 构造出来的对象 obj」的原型,即 obj.proto === Object.prototype

  • Object.proto 是 Object 的原型,由于 Object 是函数,而所有函数的原型都是 Function.prototype,所以 Object.proto === Function.prototype

  • Object.prototye 不是 Object 的原型,Object.proto 才是 Object 的原型(还记着之前答过「x.原型 等价于 x.proto」吗,现在只不过是把 x 替换成 Object。很多人都搞不清楚 Object.proto 和 Object.prototype 哪一个才是 Object 的原型,其实只要记住公式就好办了)

分别用function和class写一个 Person 构造函数

function

    function Person(name, age){
        this.name = name
        this.age = age
    }
    Person.prototype.sayHi = function(){
      console.log(`你好,我是${this.name}`)
      或者
      console.log('你好,我是'+this.name)
    }

class

    class Person{
      constructor(name, age){
          this.name = name
          this.age = age
      }
      sayHi(){
           console.log(`你好,我是${this.name}`)
          或者
          console.log('你好,我是'+this.name)
      }
    }