深入理解对象(创建和继承)

对象

  • 什么是对象

    ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数”

    • 属性的类型
      访问器属性:[[Configurable]],[[Enumerable]],[[Writeable]],[[Value]],访问器属性:[[Configurable]],[[Enumerable]],[[Get]],[[Set]].如果要修改以上属性的特性,需要调用Object.defineProperty(),其参数为属性所在的对象、属性的名字、一个描述符对象。定义多个属性Object.defineProperties(要修改的对象,修改后的对象),读取这些特性:Object.getOwnPropertyDescriptor()
  • 创建对象

    • 工厂模式(通过函数封装以特定接口创建对象的细节)

      function createPerson (name, age, job) {
      let o = new Object();
      o.name = name;
      o.age = age;
      o.job = job;
      o.sayName = function(){
        alert(this.name)
      };
      return o;
      }
      let person = createPerson('hy', '20', 'software Engineer')
      // 没有解决对象识别问题(即怎样知道一个对象的类型)
    • 构造函数模式(自定义构造函数)

      function Person (name, age, job) {
      this.name = name;
      this.age = age;
      this.job = job;
      this.sayName = function(){
        alert(this.name)
      };
      }
      let person = createPerson('hy', '20', 'software Engineer')
      // 没有显示创建对象、将属性和方法赋给了this、没有return

    缺点:不同实例上的同名函数是不相等的,即每个实例都包含一个不相同的Function实例

    • 原型模式(将属性和方法添加到原型上,所有的实例共享属性和方法)

      面试题:prototype 和 proto 有什么区别?
      prototype 是函数的,指向函数的原型对象,创建一个实例后,实例内部有个[[prototype]],脚本里无法访问,但浏览器有一个proto指向构造函数的原型对象(即当函数为构造函数是,prototype和proto指向同一个原型对象)

    function Person = {
    
    }
    Person.prototype.name = 'hy';
    Person.prototype.age = 20;
    Person.prototype.job = 'software Enginner'
    Person.prototype.sayName = function(){
    alert(this.name)
    }
    // 更简单的原型语法
    
    可以通过hasOwnProperty()来检测属性存在于哪里,只有当属性存在于实例上,才会返回true in操作符,只要能访问到属性就返回true,不论是原型上还是实例上。 for-in 循环返回能通过对象访问的所有可枚举的属性,要访问实例上所有可枚举属性,使用Object.keys()
    • 组合使用构造函数模式和原型模式(构造函数模式用于定义实例属性,原型模式定义方法和共享属性)
      function Person(name, age, job) {
      this.name = name;
      this.age = age;
      this.job = job;
      this.friends = ['yh', 'hy']
      }
      
      Person.prototype = {
      constructor: Person,
      sayName: function (){
        alert(this.name)
      }
      }

    instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
    typeof 一般用来测试基本类型

  • 继承对象

    • 原型链
      每个实例对象(object )都有一个私有属性(称之为 proto)指向它的原型对象(prototype)。该原型对象也有一个自己的原型对象 ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
    • 基于原型链实现继承(基本模式)
    function SuperType(){
    this.property = true;
    }
    SuperType.prototrpt.getSuperValue = function(){
    return this.property;
    };
    // 组合使用构造函数和原型模式
    function SubType(){
    this.subproperty = false;
    }
    SubType.prototype = new SuperType(); // !important
    SubType.prototype.getSubValue = function(){
    return this.subproperty;
    };
    var instance = newSubType();
    // 让原型对象等于父级的实例

    存在的问题:不能向超类型的构造函数中传递参数,引用类型的问题

    • 借用构造函数
    function SuperType(name){
      this.name = name;
    }
    function SubType(){
    SuperType.call(this, 'hy')
      this.age = 20;
    }
    var instance = new SubType()
    // 存在的问题:方法都在构造函数中定义,无法进行函数复用
    • 组合继承(最常用)
      将原型链和借用构造函数结合在一起

      function SuperType(name) {
      this.name = name;
      this.colors = ['red', 'blue', 'green'];
      }
      SuperType.prototype.sayName = function() {
      alert(this.name)
      }
      function SubType(name, age) {
      SuperType.call(this, name);
      this.age = age;
      }
      SubType.prototype = new SuperType();
      SubType.prototype.constructor = SubType();
      SubType.prototype.sayAge = function(){
      alert(this.age)
      }
    • 原型式继承

      function object(o) {
      function F() {}
      F.prototypr = o;
      return new F();
      }
      // ECMAScript5 通过Object.create()规范了原型式继承
    • 寄生式继承

      function craete(original){
      var clone = object(original); // object()不是必须的,任何能够返回新对象的函数都可以
      clone.sayHi = function() {
        alert('Hi')
      }
      return clone;
      }
      // 和构造函数类似
    • 寄生组合式继承

      function inherit(SubType, SuperType){
      var prototype = object(SuperType.prototype); // 创建对象
      prototype.constructor = SubType();           // 增强对象 
      subType.prototype = prototype;               // 指定对象
      }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值