构造函数模式-拓展

先看如下构造函数

    function Fn() {
        // this -> f1
        this.x = 100;
        this.getX = function () {
            // this -> 需要看getX执行的时候才知道
            console.log(this.x);
        }
    }
    var f1 = new Fn; // -> 此处()可省略
    f1.getX(); // 方法中的this -> f1 -> 100
    var ss = f1.getX;
    ss(); // this -> window -> undefined
  1. 在构造函数模式中,new Fn执行,如果Fn中不需要传递参数的话,后面的"()"可以省略。

  2. this的问题: 在类中出现的this.xxx = xxx; 中的this都是当前类的实例,而某一个属性值(方法),方法中的this需要看方法执行的时候,前面是否有".",才能知道this是谁。

  1. 类有普通函数的一面,当函数执行的时候,var num 其实只是当前形成的私有作用域中的私有变量而已,它和我们的f1这个实例没有任何的关系;只有this.xxx = xxx;才相当于f1这个实例增加了私有的属性和方法,才和f1有关系。
    function Fn() {
        var num = 10;
        this.x = 100; // f1.x = 100;
        this.getX = function () { // f1.getx = function() {...}
            console.log(this.x);
        }
        return 100;
        return {a: '1'};
    }
    var f1 = new Fn();
    console.log(f1.num); // undefined
  1. 在构造函数模式中,浏览器会默认的把实例返回(返回的是一个对象数据类型);如果我们自己手动写了return返回,这是分为两种情况:
    第一种情况: 是返回的是基本数据类型,那么当前的实例是不会改变的,例如return 100;此时f1还是Fn()类的实例。
    第二种情况: 如果返回的是引用数据类型的值,当前的实例会被返回的引用数据替换了,例如return {a: '1';}, 此时f1就不再是Fn()的实例了,而是 {a: '1'};
console.log(f1);
  1. 检测某一个实例是否属于这一个类,可以使用instanceof
    console.log(f1 instanceof Fn); // -> true
    console.log(f1 instanceof Array); // -> false
    console.log(f1 instanceof Object); // -> true 因为所有的实例都是对象数据类型的
    // 而每一个对象数据类型,而每一个对象数据类型都是Object这个内置类的一个实例,所以f1也是它的一个实例
    // 对于检测数据类型来说,typeof有自己的局限性,它不能细分Object下的对象、数组、正则等。
    var a = [];
    console.log(a instanceof Array); // -> true 说明a是一个数组
    function Fn() {
        this.x = 100;
        this.getX = function () {
            console.log(this.x);
        }
    }
    var f1 = new Fn();
    var f2 = new Fn();
  1. f1和f2都是Fn这个类的一个实例,都拥有x和getX两个属性,但是这两个属性是各自的私有的属性,所以:
    console.log(f1.getX === f2.getX); // -> false
    // in: 检测某一个属性是否属于这个对象,attr in object,不管是私有的还是公有的属性,只要存在,用in来检测都是true
    console.log('getX' in f1); // true -> 是它的属性
    // hasOwnProperty: 用来检测某一个属性是否为这个对象的"私有属性",这个方法只能检测私有的属性
    console.log(f1.hasOwnProperty('getX')); // true

思考:检测某一个属性是否是该对象的"公有属性"?

    function hasPublicProperty(obj, attr) {
        if (attr in obj && !obj.hasOwnProperty(attr)) {
            return true;
        }
        return false;
    }
    console.log(hasPublicProperty(f1, 'getX')); // -> false

你可能感兴趣的:(构造函数模式-拓展)