JavaScript中this的学习

本篇文章参考了以下大大们的博客http://www.ruanyifeng.com/blog/2018/06/javascript-this.html
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
https://segmentfault.com/a/1190000012772040

1. 简述this

函数是一个单独的值,能够在不同的环境(上下文)中执行。this的出现,就是让我们能够取得到当前运行环境,进而获取到当前运行环境的一些值。

1.1 以函数形式调用

仅仅是以函数的形式调用时,this指的就是window

var fun = function(){
    console.log(this)
}
fun() //以普通函数调用

在这里插入图片描述

1.2 以对象的方法调用

对象的方法来调用时,this指向的就是调用方法的那个对象

var obj = {
    fun:function(){
        console.log(this)
    },
    name:"obj"
}
obj.fun() //以对象的方法调用

在这里插入图片描述

1.3 call,apply,bind方法调用

使用call,apply或bind方法时,this指向的是作为参数传入这些方法的对象

var fun = function(){
    console.log(this)
}
var obj = {
    name:"obj"
}
var obj1 = {
    name:"obj1"
}
fun.call(obj)
fun.apply(obj1)

在这里插入图片描述

1.4 构造函数调用时

构造函数调用时(new),this指向新创建的那个对象

function Person(name){
    this.name = name
    console.log(this)
}
var f1 = new Person("cjx")
console.log(typeof(f1)) 

在这里插入图片描述

1.5 箭头函数时

this是函数定义时所处的对象(我认为是函数定义时所处的对象所指的this?)
具体分析可以看我的箭头函数学习笔记:https://blog.csdn.net/hongtaochi0464/article/details/91379881

2. call,apply,bind详解

2.1 apply

语法:func.apply(thisArg,[argsArray])
参数
(1)thisArg,可选参数。用于指定func函数运行时this值所指的对象。如果设置为null或undefined(即不传参)将指向全局对象window
(2)argsArray,可选参数。传一个数组或类数组对象。数组中的元素将作为参数传给func函数。

示例:用apply将数组添加到另一个数组
如果我们想要将数组elements拼接到数组array中,应该怎么实现呢?

var array = ['a','b'];
var elements = [0,1,2];
array.push.apply(array,elements);
console.log(array);

在这里插入图片描述

2.2 call

该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组。
语法:fun.call(thisArg,arg1,arg2,…)
参数
(1)thisArg,可选参数。用于指定func函数运行时this值所指的对象。如果设置为null或undefined(即不传参)将指向全局对象window
(2)arg1,arg2,… 可选对象,指定的参数列表。

示例:使用call方法调用父构造函数
在一个子构造函数中,可以通过调用父构造函数的call方法来实现继承。

function Product(name, price) {//父构造函数
  this.name = name;
  this.price = price;
}

function Food(name, price) {
  Product.call(this, name, price);//子类Food使用call继承父构造函数
  this.category = 'food';
}

function Toy(name, price) {
  Product.call(this, name, price);
  this.category = 'toy';
}

var cheese = new Food('feta', 5);
console.log(cheese)
var fun = new Toy('robot', 40);
console.log(fun)

在这里插入图片描述

2.3 bind

与call()和apply()会直接调用函数不同,bind()方法会创建一个新的函数。如:

function test(){
    return this
}
var obj = {name:"obj"}
var t1 = test.bind(obj)
console.log(typeof t1)
console.log("this绑定到了:",t1())

在这里插入图片描述
语法:fun.bind(thisArg[, arg1[, arg2[, …]]])
参数
(1)thisArg,可选参数。用于指定func函数运行时this值所指的对象
(2)arg1,arg2,… 可选参数,用于作为预设参数。当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。

2.4 小总结

我们来用一个小例子来看看bind和call(apply)的区别。妈妈会说话(具有speak的方法),孩子目前还不会说话。如何让小孩说话?(使用call) 如何教小孩会说话?(使用bind)

var mother = {
    name:"mom",
    speak:function(){
        console.log(this.name+" speak something")
    }
}
var kid = {
    name:"kid"
}
mother.speak() //妈妈说话
mother.speak.call(kid) //妈妈教小孩说话(小孩用妈妈说话的方法)
kid.speak = mother.speak.bind(kid); //妈妈教会了小孩说话(小孩继承了妈妈说话的方法)
console.log(kid);//可以看到kid对象具有了speak方法
kid.speak() //小孩说话

在这里插入图片描述
如果想要改变一个函数的this指向的时候可以考虑使用call apply bind方法。
(1)参数不多,可以考虑使用call
(2)参数很多,则可以用数组将参数整理好,使用apply
(3)如果你想生成一个新的函数长期绑定某个函数给某个对象使用,使用bind

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值