构造函数-组合模式-继承

本文介绍了JavaScript中的构造函数模式,强调了构造函数的本质是函数,使用new操作符时成为构造函数。讨论了构造函数与工厂模式的区别,并探讨了argument对象的用途。接着深入讲解了组合模式、动态原型、寄生构造等继承模式,以及严格模式下的注意事项。文章还比较了经典继承、原型式继承、组合继承、寄生式继承和寄生组合继承等不同继承方式的优缺点。
摘要由CSDN通过智能技术生成

构造函数模式

this 调用函数对象的本身

什么是构造函数?

构造函数前用new,调用的方式与普通函数不同。但是本质上就是函数。构造函数与普通函数是强行分别出来的。

任何函数只要是有new操作的,则一定为构造函数。否则与其他函数无区别

构造函数与工厂模式的区别

  • 无显示的创建对象
  • 属性和方法直接赋值给this
  • 无return语句
  • 构造函数名大写
如果直接运行构造函数呢?

​ 构造只是可以创建对象。

​ 如果无new则是全局运行(window)

new后方法地址不同:

xiaohong.sayName!=xiaozhang.sayName

非引用类型则是开辟新的位置。

实例._proto_=Array.prototype

argument

返回数组,加了… 则是参数的逆运算,将一个数组转化为逗号分隔的参数序列

30 模式

30.1 组合模式

//需要独一无二 开辟自己空间则用构造函数模式
function Person(name,age){
	this.age=age;
	this.friend=['mary','tom'];
}
//追求可复用
Person.prototypoe.name="chen";
Person.prototype.sayName=function(){
	console.log(this.name);
}

let zhang =new Person("zhang",10);

组合模式是目前最广泛的自定义类型的方法

30.2 动态原型

将所有方法放到构造函数内部(做判断

function Person(name,age){
	this.age=age;
	this.friend=['mary','tom'];
}
if(typeof this.name !=="function"){	//此开关可以是任意的
	Person.prototype.sayName=fucntion(){	  //下一次才会有实例方法
	console.log(this.name);
	}
}

此原型可以检测网络状态

不能用对象的字面量重写原型,会切断实例与原型的联系(无constructor

30.3 寄生构造

像工厂模式,唯一不同的是需要new操作符

function Person(name,age){
	//寄生意味先在此 let o1=new Person(); 如果此行有,则下一行
	let o=new Object();
	o.name=name;
	o.age=age;
	o.friend=['mary','tom'];
	o.sayName=function(){
		console.log(this.name);
	};
	//return o;     //+加了这个则为寄生。Object实例
	//return o1;		//不返回值 默认返回新对象实例-Person实例
}

let zhang=Person("zhang",10); //工厂模式,Object创建,要加return o 
let yin=new Person("yin",20); //构造模式

寄生则意味着“截胡”——在构造函数里寄生工厂,要调用则加return o(则可以截胡到,就会调用工厂模式。

寄生的使用

对于顶级对象的方法修改:

function addArray (type,name,age){
	let a;
	switch (type){
		case "Array":
			a=new Array();
			break;	
		case "Object":
			a=new Object();
			break;	
	}
	a.name=name;
	a.age=age;
	a.sayName=fucntion(){
		log(this.name)
	}
	return a;     			//若删除后只为普通构造函数
}

(最后闯出来的构造函数对象是其他的)=> 寄生

											例如Array,Object等

30.4 严格模式

大型企业项目为了安全起见

1.用的非常少

2.eval() 将字符串当做是函数立马执行

传入的不变 保持最开始的形式

1.无new

2.不用this

构造函数与构造函数见instanceof 检测不出(只能检测构造与实例

先执行函数参数,再执行函数体,ES6在参数里使用,则不能在里面用严格模式。

30.5 原型继承

31 继承

31.1 经典继承

1.call方法(伪造对象

使用方法:

fn.call({对象},参数1,参数2...)

​ fn为函数:对象调用fn,this指向调用的对象。

Signal.prototype.ch.call("tom",188)		//相当于tom.Signal.prototype.ch(188)

手写call方法:

  Function.prototype.call2 = function (thisArg) {
            //先判断是不是空的,是的话指向window,不是的话采用Object方法,将thisArg传进去,返回那个对象
            thisArg = thisArg == null ? window : Object(thisArg);
            // log( Object(thisArg));		Object方法,将thisArg传进去,返回那个对象
            // log(thisArg); //调用的对象
            log(this);			//全程指向那个方法fn
            //然后将剩下的使用[...rest]将它变为数组,然后返回一个新对象(slice复制
            let args = [...arguments].slice(1);
            // log(args)//新参数 
            let symbolFn = Symbol('fn');
            thisArg[symbolFn] = this;   //方法  调用对象.方法
            let res = thisArg[symbolFn](...args);//调用对象.方法(参数)
            delete thisArg[symbolFn];
            return res;
        }

2.apply方法

使用方法:

fn.call({对象},[参数1,参数2...])
//fn.call({},[...a,...b]);

与call一样,仅仅是多了“ [ ] ”

使用场景:用数组参数使用。

3.bind方法

使用方法:

fn.bind({对象},参数1,参数2...)

返回对象数组本身(重新创建新函数,可以先固定死函数

总结:

1.子类型构造函数里用超类构造函数。

2.是借用,并不是完整继承,但是拥有超类的函数方法

例子:
function yeye(){
	this.colors=['green','red'];
}
function Baba(){
	yeye.call(this) 		//函数在运行而已(o.yeye()
}

let o=new Baba();
o instanceof Baba	//true
o instanceof yeye 	//false

↑仅仅是调用函数而已(伪继承

优点:原型链更简单、可以传参数(父向子传

31.2 组合继承

function SuperType(name){
	this.name=name;
	this.colors=['red','green'];
}
SuperType.prototype.sayName=function(){
	log(this.name);
}
function SubType(name,age){
	//继承属性!
	SuperType.call(this.name);
	this.age=age;
}
//继承方法
SubType.prototype=new SuperType();		//一个对象的实例可以作为另一个对象的原型
SubType.prototype.constructor=SubType;
SubType.prototype.sayAge=funtion (){
    log(this.age);
}
var instance1=new SubType("wan",18);
总结:

1.都无SuperType,仅在SubType中设SuperType.call(this.参数)

2.需动手定义constructor

3.缺点:需调用两次构造函数

31.3 原型式继承

function object(o){
    funtion F(){}
        F.prototype=o;
        return new F();
    }
    var person={
        name:'wan',
        friends:['tom','jerry']
    };


var b=object(person);
b.name="gray";
总结:

借助原型可以给予已有的对象创建对象,不必自定义类型

31.4 寄生式继承

和组合继承类似

31.5 寄生组合继承

function SuperType(name){
	this.name=name;
	this.colors=['red','green'];
}
SuperType.prototype.sayName=function(){
	log(this.name);
}
function SubType(name,age){
	//继承属性!
	SuperType.call(this.name);
	this.age=age;
}
function object(o){
    funtion F(){}
        F.prototype=o;
        return new F();
    }
function inhertPrototype(SubType,SuperType){
    var prototype=object(SuperType.prototype);
    prototype.constructor=SubType;	//↑对
    SubType.prototype=prototype;	//指定对象
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值