J41 构造函数

156 阅读4分钟

1.普通函数

把Func函数执行(当做普通函数执行);方法中的THIS:window

function Func(name, age) {
	//=>this:window
	this.name = name;
	this.age = age;
}
let f1 = Func('张三', 10);
console.log(f1); //=>undefined 因为无返回值函数内没有return
console.log(window.name, window.age); //=>张三 10

let f2 = Func('李四',30);
console.log(f2); //=>undefined 因为无返回值函数内没有return
console.log(window.name, window.age); //=>李四 30

2.构造函数

ES3语法中:new 函数() => 这种方式就是基于构造函数的方式来执行

  • 1.Func不在被称为普通函数,而是叫做构造函数(也就是我们所谓的自定义类)

  • 2.返回的结果也不再基于RETURN来判断返回值,返回的结果是当前类的一个实例

  • 3.想创建自定义类和创建类的实例,只需要在执行的时候 不在 "函数()" 普通函数执行;而是 "new 函数()" 执行,也就是构造函数执行,这样方法被称为类,返回结果被称为类的实例;

    function Func(name, age) { //代码执行之前,创建一个实例对象(堆) //让THIS指向实例对象 //=>this.xxx=xxx 都是在给实例对象设置私有的属性和方法 this.name = name; this.age = age; //如果函数没有return,默认会把创建的实例对象返回 } //1.张三相当于在找方法中this作为属性名;10也相当于在找方法中this作为属性名 //2.new相当于创建的类Func在找实例,这个实例是f1 let f1 = new Func('张三', 10);//{name:'张三',age:10}

    //1.李四相当于在找方法中this作为属性名;10也相当于在找方法中this作为属性名 //2.new相当于创建的类Func在找实例,这个实例是f2 let f2 = new Func('李四'', 30);//{name:'李四',age:30} console.log(f1);//f1函数本身 console.log(f2);//f2函数本身 //FALSE 每次都是创建一个新的实例,每一个实例和其他实例都是一个单独的对象(个体),互相之间不冲突 console.log(f1 === f2);

3.构造函数练习

约定规范:类名的第一个字母一般都是大写的

  • 1.构造函数执行,由于具备普通函数特征,所以在私有上下文中可能会出现一些私有变量,但是这些私有变量和实例没有必然的联系,私有上下文中的THIS才是实例,所以只有写THIS.XXX=XXX的操作,才是给实例设置私有属性;

  • 2.实例的私有属性和上下文中的私有变量不是一个东西

  • 3.当前类的每一个实例都是单独的一个对象,实例和实例之间是独立的

  • 4.在构造函数的函数体中,基于 THIS.XXX=XXX 给实例设置的属性和方法都是自己私有的,和其它实例中的属性和方法不冲突

    function Fn(x) { let y = 20; this.total = x + y; this.say = function () { console.log(${x} + ${y} = ${this.total}); }; } let f1 = Fn(10); //=>f1=undefined let f2 = new Fn(10); //=>f2实例对象 let f3 = new Fn(20); //=>f3实例对象

    console.log(f2.total); //=>30 console.log(f2.x); //=>undefined 此时函数体中没有return console.log(f3.y); //=>undefined 此时函数体中没有return console.log(f1 === f2); //=>FALSE console.log(f2 === f3); //=>FALSE f2.say(); //=>"10+20=30" //FALSE 都是当前实例的私有属性和方法(所有出现在构造函数的函数体中的 this.xxx=xxx 操作,都是设置私有的属性和方法) console.log(f2.say === f3.say); //Uncaught TypeError: Cannot read property 'total' of undefined f1不是对象,只有对象才能操作键值对 console.log(f1.total); console.log(window.total); //=>30 window.say(); //=>"10+20=30"

4.普通函数和构造函数的区别

  • 1、普通函数不加小小括号就是函数本身,加小括号就是执行函数

  • 2、如果构造函数,不加小括号,就是没有传参,但是自带了return;如果带小括号就是代表传参

    /*

    • 普通函数
    • Fn 是函数本身(不是执行)
    • Fn() 函数执行
    • 构造函数
    • new Fn(); 构造函数执行 =>有参数new 创建了一个类
    • new Fn; 构造函数执行(这种方式不能给函数传递实参了) =>无参数new */

    function Fn() { this.x = 100; this.y = 200; }

    let f1 = new Fn(); console.log(f1);

    let f2 = new Fn; console.log(f2);

6.数据类型检测

instanceof:检测当前实例是否属于这个类(或者检测当前值是否为某个类的实例)

  • 1.值 instanceof 类

  • 2.是它的实例返回TRUE,反之返回FALSE

    function Fn() {} let f1 = new Fn; //=>TRUE 检测当前实例是否属于这个类 console.log(f1 instanceof Fn); //=>FALSE 检测当前实例是否属于这个类 console.log(f1 instanceof Array);

  • 3.局限1:instanceof不适用于基本数据类型检测

    console.log(100 instanceof Number); //=>FALSE

  • 4.应用场景:区分对象中的特殊数据格式,例如数组或者正则

    let arr = [10, 20]; let reg = /^$/; //=>"object" typeof不能具体检测对象类型的细分 console.log(typeof arr); console.log(typeof reg); //=>"object" //=>TRUE 检测arr这个数据是不是一个 数组 console.log(arr instanceof Array); console.log(arr instanceof RegExp); //=>FALSE

7.检测当前的某一个属性是否为实例

1.hasOwnProperty:检测当前的某一个属性是否为实例(或者对象)的私有属性

  • 1.对象.hasOwnProperty(属性)
  • 2.是私有的属性返回TRUE,如果不是对象的属性或者不是私有的属性都返回FALSE
  1. in:这个操作符也是检测当前属性是否为对象的属性
  • 1.属性 in 对象

  • 2.只要是对象的属性(不管是公有还是私有的属性)结果都是TRUE

    function Fn() { // 构造函数体中出现的 this.xxx = xxx 都是给当前实例设置的私有属性 this.x = 100; this.y = 200; this.say = function () { console.log(x + y); }; } let f1 = new Fn; let f2 = new Fn; console.log(f1.say === f2.say); //=>false

    // 检测当前的某一个属性是否为实例 console.log(f1.hasOwnProperty('say'));//=>true //因为你连这个属性都没有 console.log(f1.hasOwnProperty('name')); //=>false //=> toString一定是f1对象的属性,否则f1也不可能调用 //这个方法toString不是它的私有属性,是他的公有属性 console.log(f1.toString()); //"[object Object]" console.log(f1.hasOwnProperty('toString')); //=>false
    console.log('say' in f1); //=>true console.log('toString' in f1); //=>true console.log('name' in f1); //=>false

8.检测某一个属性是否为当前对象的公共属性

需求:检测某一个属性是否为当前对象的公共属性(是他的属性,但是还不是私有的)

  • 检测ATTR是否为OBJ的公有属性

    function Fn() { this.x = 100; this.y = 200; this.say = function () { console.log(x + y); }; } let f1 = new Fn; let f2 = new Fn; console.log(f1.say === f2.say); function myHasPublicProperty(attr, obj) { // 1.需要是它的属性 =>IN检测为TRUE // 2.不是它的私有属性 =>HASOWNPROPERTY检测为FALSE // return ((attr in obj) === true) && (obj.hasOwnProperty(attr) === false); return (attr in obj) && !obj.hasOwnProperty(attr); } console.log(myHasPublicProperty('say', f1)); //=>false console.log(myHasPublicProperty('name', f1)); //=>false console.log(myHasPublicProperty('toString', f1)); //=>true