函数的调用(6种)
//1、普通函数
function fn(){
}
// fn() 或者 fn.call()
//2、对象的方法
var o={
fn:function(){
}
}
//o.fn()
//3、构造函数
function fn(){}
// new fn()
//4、绑定事件函数
// btn.οnclick=function(){} 点击按钮即可调用
//5、定时器函数
// setInterval(function(){},1000) 自动1秒钟调用一次
//6、立即执行函数
(function(){
})()
//自动调用
this指向
调用方式的不同决定了this 的指向不同,一般指向我们的调用者
调用方式 | this指向 |
---|---|
普通函数调用 | window |
构造函数调用 | 实例对象、原型对象里的方法指向实例对象 |
对象方法调用 | 该方法所属对象 |
事件绑定方法 | 绑定事件对象 |
定时器函数 | window |
立即执行函数 | window |
分析this指向
function foo(){
return this
}
var o={
name:'Jim',
func:foo
}
console.log(foo()===window) //true 对应第2种情况
console.log(o.func()===o) //true 对应第3种情况
更改this指向(call、apply、bind方法)
JavaScript 为专门提供了一些函数方法来处理函数内部 this 的指向问题,常用的有
bind()、call()、apply()
三种方法。
方法 | 说明 | 使用 |
---|---|---|
call(obj,arg1,arg2,…) |
调用函数,提供参数的方式是 参数列表 ,函数返回值 |
主要用来实现 继承 |
apply(obj,argArray) |
调用函数,提供参数的方式是 参数数组(包括伪数组) ,函数返回值 |
借助 Math对象 实现数组最大值、最小值 |
bind(obj,arg1,arg2,…) |
不调用函数,提供参数方式 同call() ,返回指定this值和初始化参数改造的 原函数拷贝 (返回是改变之后的新函数) |
可实现 提前绑定 的效果。在绑定时,还可以提前传入调用函数时的参数,比如改变定时器内部的this指向 |
//改变this指向
var Person={
name:'张三'
}
function method(a,b){
console.log(this)
console.log(a+","+b)
console.log(this.name)
console.log('---------------------')
}
method('a','b')
method.apply(Person,['a','b'])
method.call(Person,'a','b')
method.bind(Person,'a','b')() //必须得调用 否则就只是绑定了而已
对call()方法应用:
在构造函数实现继承父类属性例子中
对apply()方法应用:
借助Math对象对数组对象求最大值
var arr=[1,55,53,88,56]
var max=Math.max.apply(Math,arr)
console.log(max) //输出:88
对bind()方法理解:
function method(a,b){
console.log(this.name+a+b)
}
var name='张三'
method('1','2') //输出结果为张三12 该方法中this指的是window
var test=method.bind({name:'李四'},'3','4') //method方法绑定了{name:'李四'}对象
test() //输出:李四34 method中的 this 指向就是{name:'李四'}的对象
对bind()方法应用:
//实现有一个按钮,点击后就禁用按钮,3秒之后自动开启这个按钮
//bind方法
var btn=document.querySelector('button')
btn.onclick=function(){
this.disabled=true //这个this指的是btn这个按钮
setTimeout(function(){
// this.disabled=false //这个this指的是window 因此没有效果
}.bind(this),3000) //这个this指的是btn这个按钮
}
继承
ES6之前并没有提供 extends 继承。可以通过
构造函数+原型对象
模拟实现继承,被称为
组合继承
构造函数实现继承父类属性
原理:
通过
call()方法
将父类的this指向子类的this,这样就可以实现子类继承父类的属性
// 利用构造函数继承父类属性 (ES5)
function Father(name, age) {
this.name = name
this.age = age
}
function Son(name, age, score) {
Father.call(this, name, age) //该this指向子构造函数实例对象 子继承父属性
this.score = score
}
var son = new Son('张三', 20, 90)
console.log(son) //输出结果:Son {name: "张三", age: 20, score: 90}
ES6中继承父属性
:使用super关键字即可
// 使用super继承(ES6)
class Father {
constructor(name, age) {
this.name = name
this.age = age
}
}
class Son extends Father {
constructor(name, age, score) {
super(name, age)
this.score = score
}
}
var son = new Son('张三', 20, 90)
console.log(son) //输出结果:Son {name: "张三", age: 20, score: 90}
原型对象实现继承父类方法
一般情况下,对象的方法都在构造函数的原型对象中设置,通过构造函数无法继承父类方法。 可将父类的
实例对象
作为子类的
原型对象
来使用
核心原理:
-
将子类所共享的方法提取出来,让
子类的 prototype 原型对象 = new 父类()的实例对象
-
本质:子类原型对象等于是实例化父类,因为父类实例化之后另外
开辟空间
,就
不会影响原来父类原型对象
-
将子类的
constructor
重新指向子类的构造函数
// 使用原型对象继承父方法(ES5)
function Father() { }
Father.prototype.money = function () { //通过原型对象给Father添加一个money匿名函数
console.log(1000)
}
function Son() { }
//Son.prototype=Father.prototype //让子原型对象指向父原型对象
//不能够实现,如果修改子原型,父也跟随改变
Son.prototype = new Father() //将父类的实例对象作为子类的原型对象
//作用:实例对象存在__protp__属性可指向父类原型对象,即子类可以使用父类的方法money() 实现继承
//Son.protope.constructor此时指向的是Father构造函数
//因为利用对象的形式修改了原型对象,导致被覆盖,所以应指回Son构造函数
Son.prototype.constructor = Son //将原型对象的constructor属性指向子类
Son.prototype.exam = function () {
console.log(10000)
} //为子类增加exam()方法
new Son().money() //调用父类money()方法 输出结果:1000
new Father().exam() //输出结果:报错 Uncaught TypeError: (intermediate value).exam is not a function
console.log(Father.prototype.exam) //子类不影响父类,父类原型对象没有exam 输出结果:undefined
ES6中继承父方法
// ES6 继承父方法
class Father {
constructor(name, age) {
this.name = name
this.age = age
}
money = function () {
console.log(1000)
}
}
class Son extends Father {
constructor(name, age, score) {
super(name, age)
this.score = score
}
exam = function () {
console.log(10000)
}
}
new Son().money() //输出结果:1000
new Father().exam() //输出结果:报错 Uncaught TypeError: (intermediate value).exam is not a function
版权声明:本文为weixin_45654582原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。