zoukankan      html  css  js  c++  java
  • 菜鸟快飞之JavaScript对象、原型、继承(二)

      上一节写了创建对象的三种方法,而其中通过函数创建对象的方式又有三种模式,分别是工厂模式、构造函数模式、原型模式。而这三种模式最常用的则是原型模式。还是上栗子:

      工厂模式:

    function Fun1(name,age){
        var obj = {};
        obj.name = name;
        obj.age = age;
        obj.sayNmae = function(){
            return this.name;
        };
        return obj;
    }
    
    var p1 = Fun1('xiaohong', 22);
    var p2 = Fun1('xiaoming', 25);
    
    p1 instanceof Fun1; // false

      工厂模式的缺点在于无法进行对象识别,就是知道一个对象的类型。(ps:其实我也没太搞明白这个用处,写的代码太少)

     构造函数模式:

    function Person(name,age) {
     this.name = name;
     this.age = age;
     this.sayName = function() {
      console.log('你好,我叫:' + this.name);
     };
    }
    
    var p1 = new Person('小明', 25);
    var p2 = new Person('小花', 23);
    
    p1 instanceof Person; // true

      使用构造函数模式创建对象,需要使用new操作符来创建实例,通过这种方式调用构造函数会经历以下4个过程:

        1.创建一个新对象

        2.将构造函数的作用域赋给新对象,从而使this指向新对象

        3.执行构造函数中的代码

        4.返回新对象

      现在可以使用instanceof来检测对象类型了。

      不过单纯的通过构造函数来创建对象也是有缺点的,缺点就是重复创建实例,比如上面代码中的sayName()方法会被创建两次。

      组合使用构造函数模式和原型模式:

      因为方法sayName()是可以共享的,所以我们不需要让它多次创建,为了解决这个问题,我们可以把方法sayName()拿出来,放在函数Persorn的外面,但是这样做就体现不出封装性了,所以这个时候需要的就是原型模式了。

      构造函数模式用来定义实例的属性,原型模式用来定义共享的方法和属性。

    function Person(name,age) {
        this.name = name;
        this.age = age;
    }
    Person.prototype.sayName = function() {
        console.log('你好,我叫:' + this.name);
    };
    var p1 = new Person('小明', 25);
    var p2 = new Person('小花', 23);
    
    p1.sayName(); // 你好,我叫:小明 
    p2.sayName(); // 你好,我叫:小花 

    原型

      prototype与__proto__

      每个函数都有一个prototype(原型)属性,这个属性指向一个对象,用来包含所有实例共享的属性和方法

      通过构造函数创建一个新实例后,这个实例会有一个指针[[Prototype]],我们可以通过__proto__属性来访问,这个链接存在于实例和构造函数的原型对象之间:Person.prototype === person.__proto__

      isPrototypeOf(instence)

      isPrototypeOf()方法用来确定实例构建函数的原型对象的关系。

    Person.prototype.isPrototypeOf(p1); // true

      Object.getPrototypeOf(instence)

      Object.getPrototypeOf()返回创建这个实例对象的构建函数的原型对象

    Object.getPrototypeOf(p1) === Person.prototype;  // true

      hasOwnProperty()

      hasOwnProperty()可以用来检测属性是否存在于实例对象中。

      for-in

      for-in循环中,返回实例和原型中所有可以访问,可枚举的属性。

    function Person(name,age) {
     this.name = name;
     this.age = age;
    
    }
    Person.prototype.sayName = function() {
     console.log('你好,我叫:' + this.name + '。性别:' + this.sex);
    };
    Person.prototype.sex = '男';
    var p1 = new Person('小明', 25);
    
    p1.sayName();  // 你好,我叫:小明。性别:男 
    
    for(var i in p1){
     if(p1.hasOwnProperty(i)){
      console.log(i);  // name和age
     }
    }

      Object.keys()

      Object.keys()返回给定对象上所有可枚举的实例属性。

    Object.keys(Person.prototype);  // ["sayName", "sex"]

      Object.getOwnPropertyNames()

      Object.getOwnPropertyNames()放回给定对象上所有实例属性,包括不可枚举的实例属性。

    Object.getOwnPropertyNames(Person.prototype);  // ["constructor", "sayName", "sex"]
  • 相关阅读:
    这可能是全网最轻量级、对MVVM支持最好、可定制性最高的开源WPF Chart控件了
    WPF源代码分析系列一:剖析WPF模板机制的内部实现(五)
    WPF源代码分析系列一:剖析WPF模板机制的内部实现(四)
    WPF源代码分析系列一:剖析WPF模板机制的内部实现(三)
    WPF源代码分析系列一:剖析WPF模板机制的内部实现(二)
    WPF源代码分析系列一:剖析WPF模板机制的内部实现(一)
    深入理解.NET/WPF内存泄漏
    Cocos2d-X3.0 刨根问底(九)----- 场景切换(TransitionScene)源码分析
    Cocos2d-X3.0 刨根问底(八)----- 场景(Scene)、层(Layer)相关源码分析
    Cocos2d-X3.0 刨根问底(七)----- 事件机制Event源码分析
  • 原文地址:https://www.cnblogs.com/mcbai/p/5188468.html
Copyright © 2011-2022 走看看