JS笔记(6):构造函数

639 阅读3分钟

一、构造函数:(如果无参数传递,括号可以省略)

  • new Fn;
  • new Fn();
  • new Array();
  • new Function();
  • new Object();
  • new RegExp();
  • 构造函数的返回值:当前类的实例 基于构造函数创建出来的值是引用类型(可以但不建议用构造函数模式创建基本类型值)

二、关于构造函数的this:

构造函数的this是当前类的实例

三、关于构造函数的renturn:

  • 1.return; //=>return后面不加内容,代表结束执行下面的代码
  • 2.return "123"; //=> return后面是基本类型,则返回的仍是当前类的实例(即this)
  • 3.return {name:'Tom'}; //=> return后面是引用类型,则返回的是引用类型值(即覆盖了实例)

四、关于构造函数执行的过程:

  • 1.像普通函数执行一样,形成一个私有作用域(栈内存)
    • 形参赋值(私有变量)
    • 变量提升(私有变量)
  • 2.【构造函数执行独有】在js代码自上而下执行之前,首先在当前形成的私有栈中创建一个对象(创建一个堆内存:暂时不存储任何的东西),并且让函数中的执行主体(this)指向这个新的堆内存(当前类的实例) => this === 创建的对象
  • 3.代码自上而下执行
  • 4.【构造函数执行独有】代码执行完成,把之前创建的对内存地址返回(浏览器默认返回)
  • 5.释放栈内存
         function Fn() {
            let n = '彭彭'
            this.name = '黄老板';
            this.m = n;
            // return {name:'Tom'};
        };
        Fn.prototype.a = function () {
            console.log('123');
        };
        let f = new Fn();
        console.log(f); // Fn {name: "黄老板", m: "彭彭"}
        console.log(f.n); // undefined

此例中:

  • f => Fn类的一个实例,同时是个对象(也是构造函数的返回值,是构造函数中的this)
  • new Fn() => 同f 即实例化对象
  • Fn => f 实例所属类,同时是个构造函数
        // instanceof:检测当前实例是否所属这个类
        console.log(f instanceof Fn); //true
        console.log(f instanceof Object); //true
        console.log(f instanceof Function); //flase f是实例,实例是个对象 属于Object类,不属于Function
        console.log(Fn instanceof Function); //true 所有的函数都属于Function内置类的实例
        console.log(Fn instanceof Object); //true 函数也是对象,所以属于内置基类Object

        // in: 判断对象中是否存在某个元素(无论私有属性还是在原型上的公有属性,只要存在就为true
        console.log('n' in f); // flase 'n'不属于f实例的属性,是Fn函数的属性
        console.log('m' in f); // true 
        console.log('name' in f); // true 
        console.log('a' in f); //true 

        // hasOwnProperty: 检测当前属性为对象的私有属性
        console.log(f.hasOwnProperty('n')); //false n不是私有属性,也不是公有属性,n不是f实例的属性
        console.log(f.hasOwnProperty('m')); //true
        console.log(f.hasOwnProperty('a')); //flase a是Fn类原型上的属性,属于公有属性
        

编写一个方法:检测当前属性是否为对象的公有属性

function hasPubProperty(attr,obj){
    return (attr in obj) && (obj.hasOwnProperty(attr) === false)
    //attr: 属性 obj: 对象  
    //属性在对象里,并且不是私有属性 =>即为公有属性
};
console.log(hasPubProperty('toString',f)); //true

执行题练习:

 function Fn(name,age) {
    var n = 10;
    this.name = name;
    this.age = age + n;
};
Fn(); 
var f1 = new Fn('xxx',20); 
var f2 = new Fn('aaa',30); 
console.log(f1 === f2); //false 两个不同的实例(堆内存地址)
console.log(f1.age); //30
console.log(f2.name); // 'aaa'
console.log('name' in f1); // true 
// name 和age在两个不同的实例都有存储,但是都是每个实例自己私有的属性
console.log(f1.n); // undefined 只有this.xxx = xxx的才和实例有关系,n是私有作用域中的一个私有变量而已