一、构造函数:(如果无参数传递,括号可以省略)
- 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是私有作用域中的一个私有变量而已