首页 > 编程语言 >javascript基础 this指向

javascript基础 this指向

时间:2022-11-11 18:35:10浏览次数:48  
标签:obj 函数 指向 对象 javascript 基础 window var

this指向:this永远指向一个对象;this的指向完全取决于函数调用的位置;

场景1:在全局环境中调用,this 指向 window对象
var a = 'a'
function foo() {
   console.log(this.a)
}
foo()  //  "a"
// this 指向 window对象 (小写,大写的Window是构建函数) window 是Window 的实例
// window instanceof Window true

场景2:以对象的属性方法形式调用,this 指向方法所属的那一级对象本身

function foo() {console.log(this.a)}
var obj1 = {
   a: 1,
   fn: foo,
}
var obj2 = {
   a: 2,
   fn: foo,
}
var obj3 = {
   a: 1,
   o2: obj2,
}
obj1.fn() // this 指向 obj1
obj3.o2.fn() //  this 指向 obj3.o2 即 obj2

场景3:事件绑定中的 this。也分为两种情况:函数调用this指向window对象;行内调用 this 指向 当前节点对象。

// 函数调用
<input type="button" value="按钮" onclick="clickFun()" />
// 行内调用
<input type="button" value="按钮" onclick="console.log('this;',this)" />
// 如果不是一个函数调用,直接在当前节点对象环境下使用this,那么显然this就会指向当前节点对象;

function clickFun() {
   console.log('this;', this)
   // 此函数的运行环境在全局window对象下,因此this指向window;
}

场景4:构建函数中的this。 首先要理解 构建函数 调用的过程;所以 this 总是指向 构建的对象实例本身。

function Pro() {
   this.x = '1'
   this.y = function () {}
console.log(this) // Pro {x: '1', y: ƒ} } var p = new Pro() // new 构造函数的过程 // 1.创建一个空对象; // 2.将空对象的原型(__proto__)指向构造函数的 prototype // 3.将构造函数中的 this 指向该空对象 // 4.执行代码赋值 给空对象的属性赋值; // 5.返回本对象地址

场景5:定时器 setInterval ,setTimeout 。这两本身是 window 的内置属性,接受两个参数,第一个参数允许是一个函数或者是一段可执行的 JS 代码,第二个参数则是执行前面函数或者代码的时间间隔;

var obj = {
   fun: function () {
      console.log("this:",this)
   },
}
setInterval(obj.fun, 1000)  // this指向window对象
setInterval('obj.fun()', 1000)  // this指向obj对象
// 在上面的代码中,setInterval(obj.fun,1000)的第一个参数是obj对象的fun , 因为 JS中函数可以被当做值来做引用传递,实际就是将这个函数的地址当做参数 传递给了setInterval 方法,
// 换句话说就是 setInterval 的第一参数接受了一个函数,那么此时1000毫秒后,函数的运行就已经是在window对象下了,也就是函数的调用者已经变成了window对象,所以其中的this则指向的全局window对象; // 而在setInterval('obj.fun()',1000) 中的第一个参数,实际则是传入的一 段可执行的 JS代码;1000毫秒后当 JS 引擎来执行这段代码时,则是通过 obj 对象来找到 fun函数并调用执行,
// 那么函数的运行环境依然在 对象 obj 内,所以函数内部的this也就指向了 obj 对象;

场景6:函数对象的call(), apply()方法,绑定。this 指向绑定的对象

 

function fun(){console.log(this.name))
var obj = {name:"aaa"}
fun.call(obj) // this 指向 obj

// call和apply的作用一致,区别仅仅在函数实参参数传递的方式上;
// call方法使用的语法规则 函数名称.call(obj,arg1,arg2...argN);
// 参数说明: obj:函数内this要指向的对象, arg1,arg2...argN:参数列表,参数与参数之间使用一个逗号隔开;
// apply方法使用的语法规则 函数名称.apply(obj,[arg1,arg2...,argN]) 
// 参数说明: obj :this要指向的对象 [arg1,arg2...argN] : 参数列表,要求格式为数组

var obj={name:"xxx"}
function foo(num){this.age = num;console.log("this:",this)}
var fooBO = foo.bind(obj)
fooBO(18)   //  this: {name: 'xxx', age: 18}
var fxx = foo.bind(obj,18)
fxx(19) // this: {name: 'xxx', age: 18}

// 接收参数与call相同。
// 函数调用后返回一个 匿名函数,需要再次调用

补充:常见面试题 手写call bind

// 1.所有函数都可以掉用
// 2.可以接收多个参数,至少有1个
// 3.第一个参数就是我们要去改变的this,从第二个开始是函数本身的参数
// 4.call 还有返回值 返回值是函数的执行结果
Function.__proto__.newCall = function (obj) {
    let thisObj = obj || window
    thisObj.fun = this     // this 指向getInfo
    let arg = [...arguments]
    arg.splice(0, 1)
    let returnObj = thisObj.fun(...arg)
    delete thisObj.fun
    return returnObj
}

// 手写一个 bind 方法
// 1. 可以接收多个参数,至少有1个
// 2. 返回值是函数的执行结果
// 3. 返回一个函数可以作为构造函数使用,此情况下 this 失效
Function.__proto__.newBind2 = function (obj) {
    // 可能会只拿到一部分参数
    var _this = this,
    arr = Array.prototype.slice.call(arguments, 1)
    // 也可能会只拿到一部分参数
    // 调用时拿到当前函数 getInfo 的返回值
    var newFun = function () {
       var arr2 = Array.prototype.slice.call(arguments, 0)
       var list = arr.concat(arr2)
       // 作为构造函数使用,此情况下 this 失效
       if (this instanceof newFun) {
          return _this.newCall(this, ...list)
       } else {
          return _this.newCall(obj, ...list)
       }
     }
   return newFun
}

 

。  

标签:obj,函数,指向,对象,javascript,基础,window,var
From: https://www.cnblogs.com/tongtian17/p/16881412.html

相关文章

  • JS基础之基本数据类型和包装数据类型
     leta=NewString();console.log(a);  //String{''}这个时候a就是包装类型==============================leta='';console.log(a);  //''这个时候就是基......
  • 数组基础(day11)
    笔者曾学过一阵labview,在labview中,首先创建空的数组框,随后将int整型,或str字符串型变量放入数组框内,就实现了数组的生成。1.字符串型数组labview与c的逻辑很相似。但在c语言......
  • javascript基础算法之数组元素两两相加等于某个固定值,并得出它们的对数
      letarr=[1,2,6,6,7,8,11,12,13,4,4]letnum=12functionsolution(arr,target){console.log('给出指定数组--->',arr)console.log('给出指定数......
  • javascript基础算法之判断一个随机整数是否为质数
    质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;functionsolution(num){if(num<=1){return'数据错......
  • JavaScript常用工具函数
    检测数据是不是除了symbol外的原始数据functionisStatic(value){return(typeofvalue==='string'||typeofvalue==='number'||typeofvalue......
  • JavaScript中常见的八个陷阱总结
    1.你是否尝试过对数组元素进行排序?JavaScript默认使用字典序(alphanumeric)来排序。因此, [1,2,5,10].sort()的结果是[1,10,2,5]。如果你想正确的排序,应该这样做: [1......
  • 223201062522刘晋-软件工程基础Y- 实验二 结对项目报告
    沈阳航空航天大学软件工程基础实验报告实验名称:实验二实验题目:结对项目专业软件工程学号223201062522姓名刘晋结对伙伴赵德龙指导教师孟桂英......
  • 什么是 PKI? 公钥基础设施的定义和指南
    ​ 公钥基础设施(PKI)管理Internet通信中的身份和安全性,以保护人员、设备和数据。组织依靠PKI解决方案来验证和加密流经Web服务器、数字身份、连接设备和应用程......
  • MySql - 基础学习 - JDBC
    一.为什么要学习JDBCSUM公司为了简化开发人员的操作(对数据库的统一),提供了一个规范(Java操作数据库的规范),俗称:JDBC这些规范的实现是由厂商们去做~对于开发人员来说,我们只......
  • 软件工程基础实验二
    1.任务要求本次作业要求两个人合作完成,驾驶员和导航员角色自定,鼓励大家在工作期间角色随时互换,这里会布置两个题目,请各组成员根据自己的爱好任选一题。2.题目我们在刚开......