参考学习:https://www.cnblogs.com/lisha-better/p/5684844.html
1.普通函数调用(window)
2.做为构造函数调用()
3.做为方法调用
4.使用call/apply/bind调用
5.ES6箭头函数调用(this取决于包裹箭头函数的第一个普通函数)html
**setTimeout()由window对象调用
call()参数为空,this指向window
匿名函数,this也指向window
web
在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this老是指向全局对象Windowapp
参考学习:https://www.cnblogs.com/chenwenhao/p/6980401.html
https://www.imooc.com/article/20162
https://www.cnblogs.com/humin/p/4556820.htmlsvg
关于Function和Object建立实例之间的关系
基于原型链继承的链图,对继承有个具体化的概念: (这个是核心继承部分)
上图总体的继承链函数
js继承:
1.原型链继承
特色;学习
1.要想为子类新增属性和方法,必需要在new Animal()这样的语句以后执行,不能放到构造器中 2.没法实现多继承 3.来自原型对象的全部属性被全部实例共享 4.建立子类实例时,没法向父类构造函数传参 function SuperType () { this.property = true; } SuperType.prototype.getSuperValue = function() { return this.property; }; function SubType() { this.subproperty = false; } //继承SuperType **SubType.prototype = new SuperType();** SubType.prototype.getSubValue = function() { return this.subproperty; } var instance =new SubType(); console.log(instance.getSuperValue()); // true
存在问题:this
1.包含引用类型值的原型属性会被全部实例共享(修改),而在构造函数中的基本类型和引用类型属性均不可改变(const附体)
2.建立子类型的实例时,不能向超类的构造函数中传递传递参数
3.没法实现多继承prototype
2.构造函数继承(在子类型构造函数的内部调用超类型)code
子类型构造函数中向超类型构造函数传参
问题:函数没法复用xml
function SuperType() { this.colors = ["red","blue","green"]; } function SubType() { //继承了SuperType --从新建立SuperType构造函数属性的副本 SuperType.call(this); } var instance1 = newe SubType(); instance1.colors.push("black"); console.log(instance1.colors); //"red,blue,green,black" var instances2 = new SubType(); console.log(instance2.colors); //"red,blue,green" --完美实现了继承构造函数属性
3.组合继承(避免了原型链和构造函数继承的缺陷)
弥补了方式2的缺陷,能够继承实例属性/方法,也能够继承原型属性/方法
既是子类的实例,也是父类的实例
不存在引用属性共享问题
可传参
函数可复用
缺点:
调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)
function SuperType(name) { this.name = name; this.colors = ["red","blue","green"]; } SuperType.prototype.sayName = function() { console.log(this.name); }; function SubType(name,age){ //继承属性 --从新建立SuperType构造函数属性的副本 SuperType.call(this,name); this.age = age; } //继承方法 SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function() { console.log(this.age); }; var instance1 =new SubType("Nicholas",29); instance1.colors.push("black"); console.log(instance1.colors); // "red,blue,green,black" instance1.sayName(); // "Nicholas" instance1.sayAge(); // 29 var instance2 = new SubType("Greg",22); console.log(instance2.colors); // "red,blue,green" instance2.sayName(); // "Greg" instance2.sayAge(); // 22
4.实例继承
特色:
不限制调用方式,无论是new 子类()仍是子类(),返回的对象具备相同的效果
缺点:
实例是父类的实例,不是子类的实例
不支持多继承
// 定义一个动物类 function Animal (name) { // 属性 this.name = name || 'Animal'; // 实例方法 this.sleep = function(){ console.log(this.name + '正在睡觉!'); } } // 原型方法 Animal.prototype.eat = function(food) { console.log(this.name + '正在吃:' + food); }; function Cat(name){ var instance = new Animal(); instance.name = name || 'Tom'; return instance; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // false
5.拷贝继承
特色:
支持多继承
缺点:
效率较低,内存占用高(由于要拷贝父类的属性)
没法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)
function Cat(name){ var animal = new Animal(); for(var p in animal){ Cat.prototype[p] = animal[p]; } Cat.prototype.name = name || 'Tom'; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true
6.寄生组合继承
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } (function(){ // 建立一个没有实例方法的类 var Super = function(){}; Super.prototype = Animal.prototype; //将实例做为子类的原型 Cat.prototype = new Super(); })(); // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); //true