Skip to content

面向对象

构造函数

通过new创建对象的函数:new Person()Person为构造函数

new 过程发生了什么

javascript
function _new(func){
  	// 1,创建一个新对象
	const newObj = {};
  	// 2,将构造函数的作用域赋给新对象(因此this就指向了这个对象)
  	newObj.__proto__= func.prototype;
  	// 3,执行构造函数中的代码(为这个新对象添加属性);
    func.call(newObj);
  	// 4,返回新对象
    return newObj
}

new的原理是使用构造方法构造一个新的对象 结果是:

  • 新对象的 __proto__ 指向构造它的构造函数的原型:func.prototype
  • 构造的过程 func作为构造函数被执行,上下文是新对象

函数

函数的构造函数

对象的构造函数:Function,所有的函数由Function构造创建

函数的原型对象:prototype

存在于构造函数上,拥有一个construtor属性指向创建它的构造函数

  • 对象的原型:Object.prototype

    • 所有对象的__proto__最终指向它
    • 它的__proto__null
    • 定义了valueOftoString等公用方法
  • 函数的原型:Function.prototype

    • 所有的构造函数的__proto__指向它
    • 作为对象它的__proto__最终也会指向Object.prototype

对象

对象的构造函数

对象的构造函数:Object,普通对象由Object构造函数创建

对象的原型链属性:__proto__

存在于对象上(字面量或者new出来的对象,会为新对象添加__proto__属性) 指向创建该对象的构造函数的原型

  • 构造函数则是构造函数的原型:Foo.prototype
  • 字面量对象则是:Object.prototype

javascript中防止被篡改的对象

当我们希望定义的对象不能被修改、删除和新增时,我们可以把对象设置为防篡改的。

防篡改的等级:

根据对对象的要求,我们可以把防篡改对象分为三个级别

1. 不可扩展对象

正常的对象都是可以新增属性和方法的:

javascript
  const obj = {
    title:'hello world'
  }
  obj.say = function(){
    alert(this.title)
  }

通过下面的api可以实现对对象的可扩展控制

  • Object.preventExtensions(Object):将对象设置为不可扩展
  • Object.isExtensible(Object):判断对象是否可扩展
javascript
Object.preventExtensions(obj)
obj.content = 'yes'

// undefined
console.log(obj.content)

// false
Object.isExtensible(obj)

值得注意的事:

  • 非严格模式下,对设置的对象新增属性和方法静默失败,严格模式下报错

  • 该设置针对新增属性和方法,修改和删除已有属性不影响

2. 密封对象

在不可扩展的基础上增加了不可删除设置,密封对象的[[Configurable]]描述属性会被设置为false,即不能删除,但是仍然可以修改。

通过下面的api可以实现对对象的密封设置

  • Object.seal(Object):将对象设置为密封
  • Object.isSealed(Object):判断对象是否已密封
javascript
Object.seal(obj)
delete obj.title

// hello world
console.log(obj.title)

// true
Object.isSealed(obj)

值得注意的事:

  • 非严格模式下,对设置的对象新增和删除属性静默失败,严格模式下报错

3. 冻结对象

在上面两个级别的基础上,增加了不可修改配置,防篡改级别达到最高。被设置的对象不能新增属性、修改属性、删除属性,对象的[[Writable]]描述属性也会被设置为false,即不可修改

通过下面的api可以实现对对象的冻结设置:

  • Object.freeze(Object):将对象设置为冻结
  • Object.isFrozen(Object):判断对象是否已冻结
javascript
Object.freeze(obj)

// 无效
obj.content = 'yes'

// 无效
obj.title = 'hello city'

// 无效
delete obj.title

// true
Object.isFrozen(obj)

值得注意的事:

  • 非严格模式下,对冻结的对象进行操作会静默失败,严格模式下报错

原型链

在查找新对象的属性时,如果没有,就会根据__proto__层层向上查询,直到顶层对象Object.prototype

如何理解串联

  1. 对象(函数也是对象)都是由构造函数创建的

    • 函数由Function构造
    • 对象由Object构造或其他构造函数Foo构造
  2. 函数和对象的交叉

    • 函数拥有特殊属性对象:prototype,拥有一个construtor属性指向创建它的构造函数

      • Function
    • 对象拥有特殊指针:__proto__指向创建它的构造函数的原型

      • Function.prototype:(函数也是对象)
      • Object.prototypeFoo.prototype
  3. 顶级构造函数ObjectFunction,它们由原生代码构造(prototype.constructor指向原生代码)。

  4. 对象的顶级构造函数Object.prototype.__proto__指向null

alt 面向对象