javascript中对this的认识

在学习拉勾朱德龙老师课程做的笔记,要学具体的链接在这里

https://kaiwu.lagou.com/course/courseInfo.htm?courseId=180#/detail/pc?id=3179

数据类型和函数是编程重要概念,前者储存数据,后者储存代码

在JavaScript中函数比较强大,用途比较多

可以赋值给一个变量

可以有自己的属性

可以作为参数被传递

this 关键字

this是JavaScript一个关键字,是一个指针,指向调用它的的对象

首先this指向的是一个对象,是函数执行上下文的对象

其次这个对象指向的是调用它的对象

如果调用它的不是对象或者对象不存在,则指向全局对象(严格模式下是undefined)

例子

当代码 1 执行 fun() 函数时,实际上就是通过对象 obj 来调用的,所以 this 指向对象 obj。

代码 2 也是同样的道理,通过实例 O 来调用,this 指向类实例 O。

代码 3 则可以看成是通过全局对象来调用,this 会指向全局对象(需要注意的是,严格模式下会是 undefined)。

//代码1
var obj = {
  fun(){
    console.log(this)
  }
}
obj.fun()
// {fun: ƒ} obj对象自己

//代码2
class O {
  fun(){
    console.log(this)
  }
}
var o = new O()
o.fun()
// 打印出 O

//代码3
function foo(){
  console.log(this)
}
foo()
//window

换个例子

(1)函数fn1 里面嵌套函数 fn2,里面函数打印this 指向

function fn1(){
  console.log(this)
}
function fn2(){
  fn1()
}
fn2()
//window 

this在这里没有找到调用它的对象所以指向全局对象window

(2)嵌套函数被定义到对象

function fn() {console.log(this)}
function fn2() {fn()}
var obj = {fn2}
obj.fn2() 

这里虽然fn2被放在了对象里然后执行的,但是调用fn的仍然是fn2 不是对象obj 所以this指向还是window

虽然 fn2() 作为 obj 的属性调用,但 fn2()中的 this 指向并不会传递给函数 fn()

(3)对象里有属性为数组,数组forEach循环 this指向

var obj = {
  arr:[1,2,3]
}
obj.arr.forEach(function (){
  console.log(this)
})
//undefined

看过 forEach 的说明文档便会知道,forEach接受两个参数 第一个是回调函数,第二个是指向指针,没有传默认为undefined

所以这里this指向undefined

类似的,需要传入 this 指向的函数还有:every()、find()、findIndex()、map()、some(),在使用的时候需要特别注意。

(4)创建一个类,new一个 该类的构造函数的实例,然后实例属性的函数 赋值给一个变量,该变量调用这个方法

class B{
  fun(){
    console.log(this)
  }
}
var b = new B()
var fn = b.fun
fn()
//undefined

因为该变量还是全局变量,所以this指向的还是全局,但是这里有一个隐藏知识点,es6 里面class类是严格模式

所以最后的this指向 是undefined

(5)ES6的箭头函数不会创建自己的this,他只会从自己的作用域链上一层继承this,理解为箭头函数的 this 继承自上层的 this,但在全局环境下定义仍会指向全局对象

var arrow = {fn: () => {
  console.log(this)
}}
arrow.fn()
//window

(7)this指向一个基础类型,基础类型会转换为引用对象,所以这里 this 指向的是一个值为 0 的 Number 类型对象

[0].forEach(function() {console.log(this)}, 0) // Number {0}

(8)改变this指向的常见三种方式 apply,call,bind

改变 this 指向的常见 3 种方式有 bind、call 和 apply。call 和 apply 用法功能基本类似,都是通过传入 this 指向的对象以及参数来调用函数。

区别在于传参方式,前者为逐个参数传递,后者将参数放入一个数组,以数组的形式传递。bind 有些特殊,

它不但可以绑定 this 指向也可以绑定函数参数并返回一个新的函数,当 c 调用新的函数时,绑定之后的 this 或参数将无法再被改变。

var getname = function(){
    console.log(this.name)
}
var b= getname.bind({name:'bind'})
b() //bind
var a = getname.apply({name:'apply'})
a() //apply
var c = getname.apply({name:'call'})
c() //call

由于 this 指向的不确定性,所以很容易在调用时发生意想不到的情况。在编写代码时,应尽量避免使用 this,

比如可以写成纯函数的形式,也可以通过参数来传递上下文对象。实在要使用 this 的话,

可以考虑使用 bind 等方式将其绑定。

补充 1:箭头函数

箭头函数和普通函数相比,有以下几个区别,在开发中应特别注意:

  • 不绑定arguments对象,箭头函数内访问arguments对象会报错
  • 不能用作构造器,也就是不能new 它构建的实例
  • 默认不会创建prototype原型属性
  • 不能用作 Generator() 函数,不能使用 yeild 关键字。

函数的转换

编写一个 add() 函数,支持对多个参数求和以及多次调用求和。示例如下:

add(1) // 1

add(1)(2)// 3

add(1, 2)(3, 4, 5)(6) // 21

要实现这个要求,我们必须知道函数相关的两个隐式转换函数 toString() 和 valueOf()。

toString() 函数会在打印函数的时候调用,比如 console.log、valueOf 会在获取函数原始值时调用,比如加法操作。

具体代码实现如下,在 add() 函数内部定义一个 fn() 函数并返回。

fn() 函数的主要职能就是拼接参数并返回自身,

当调用 toString() 和 valueOf() 函数时对拼接好的参数进行累加求和并返回。

function add(...args) {

  let arr = args

  function fn(...newArgs) {

    arr = [...arr, ...newArgs]

    return fn;

  }

  fn.toString = fn.valueOf = function() {

    return arr.reduce((acc, cur) => acc + parseInt(cur))

  }

  return fn

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值