javascript中this用法

一、this定义

this是一个对象,在不同情况在指向不同的对象
当一个函数被调用的时候回产生一个对象(调用方式,调用地点,参数等等)
一般来说我们用this指向全局作用域或者局部作用域来代替当前使用的对象。
使用的用途主要有:
1,作为对象方法来调用
2,作为构造函数来调用
3.使用call或者apply改变this方向后调用

二、this指向

先上结论
1、对象调用this,调用那个对象this指向那个对象
2、没有定义就直接调用this函数 ,this指向全局作用域
3、通过new的方式调用时,this永远指向new的新对象。
4、箭头函数中的this,this指向定义函数的继承上下文

对象调用

this对象调用比较简单,前面调用了那个对象,this就指向谁

var person ={name:'十九'
age:‘22’
print:function(){console.log(this)
console.log(this.nmae+‘:’+this.age)
}
}
person.print();
//this 指向的就是当前对象person

直接调用的函数

直接调用函数的时候this指向的是全局window函数

function print(){cnsole.log(this);
}
print();
//this 指向全局作用域

通过new方式调用的函数

new方法调用的函数 this永远指向新创建的对象
function person(name,age){
this.name = name ;
this.age = age ;
console.log (this);
var shijiu = new person (‘十九’,22);
//this指向的就是新穿件的new函数
}

箭头函数中的this

箭头函数中的this要注意的没有单独的this值,箭头函数中的this与定义函数的上下文相同。

const person = {a:() => {console.log(this);
}
}
//对象调用箭头函数,
person.a();//this指向的是window

三、this指向改变

改变this指向有三种方法:
call
apply
bind

call

call中第一个参数是this指向,后面的参数是this的传参,

function fn(x,y){console.log(this);  }var obj = {name:"pc"}fn(1,2);fn.call(obj,1,2);

apply

apply第一个参数是this指向,后面的参数用数组表示

function fn(x,y){console.log(this);  }var obj = {name:"pc"}fn(1,2);fn.apply(obj,[1,2]);

bind

bind只改变this指向,参数需要手动传递

function fn(x,y){console.log(this);  }var obj = {name:"zs"}fn(1,2);fn.bind(obj,1,2)();

三种方法相同点和不同点

共同点:
三者都能改变this指向,且第一个传递的参数都是this指向的对象,都是采用后续传参的形式
不同点:
call的传参是单个传递的,而apply传递的是数组,bind没有规定,单的参数和数组都可以。
call和apply的函数都是直接执行的,而bind函数会返回一个函数,调用的时候才会执行。

下面的内容是扩展内容:

手写call apply bind 源码

手写call

首先 context 为可选参数,如果不传的话默认上下文为 window ;
接下来给 context 创建一个 fn 属性,并将值设置为需要调用的函数;
因为 call 可以传入多个参数作为调用函数的参数,所以需要将参数剥离出来;
然后调用函数并将对象上的函数删除。

// this 为调用的函数
// context 是参数对象
Function.prototype.myCall = function(context){ // 判断调用者是否为函数 if(typeof this !== 'function'){ throw new TypeError('Error')
}// 不传参默认为 windowcontext = context || window // 新增 fn 属性,将值设置为需要调用的函数context.fn = this// 将 arguments 转化为数组将 call 的传参提取出来 [...arguments]const args = Array.from(arguments).slice(1)// 传参调用函数 const result = context.fn(...args)// 删除函数 delete context.fn // 返回执行结果 return result;}// 普通函数function print(age){ console.log(this.name+" "+age);}// 自定义对象var obj = { name:'pc' }// 调用函数的 call 方法print.myCall(obj,1,2,3)

手写apply

首先 context 为可选参数,如果不传的话默认上下文为 window
接下来给 context 创建一个 fn 属性,并将值设置为需要调用的函数
因为 apply 传参是数组传参,所以取得数组,将其剥离为顺序参数进行函数调用
然后调用函数并将对象上的函数删除

// 手写一个 apply 方法
Function.prototype.myApply = function(context){ // 判断调用者是否为函数 if(typeof this !== 'function'){ throw new TypeError('Error')
}// 不传参默认为 window context = context || window // 新增 fn 属性,将值设置为需要调用的函数 context.fn = this // 返回执行结果 let result; // 判断是否有参数传入 if(arguments[1]){ result = context.fn(...arguments[1]) }else{result = context.fn() }// 删除函数 delete context.fn // 返回执行结果 return result;
}
// 普通函数
function print(age,age2,age3){console.log(this.name+" "+ age + " "+ age2+" "+age3);
}
// 自定义对象
var obj = { name:'pc' }// 调用函数的 call 方法
print.myApply(obj,[1,2,3])

手写bind

判断调用者是否为函数。
截取参数,注意:这里有两种形式传参。
返回一个函数,判断外部哪种方式调用了该函数(new | 直接调用)

// 手写一个 bind 函数
Function.prototype.myBind = function (context) { // 判断调用者是否为函数 if(typeof this !== 'function'){ throw new TypeError('Error') }// 截取传递的参数 const args = Array.from(arguments).slice(1) // _this 指向调用的函数 const _this = this; // 返回一个函数 return function F(){ // 因为返回了一个函数,我们可以 new F(),所以需要判断// 对于 new 的情况来说,不会被任何方式改变 this if(this instanceof F){ return new _this(...args,...arguments) }else{return _this.apply(context,args.concat(...arguments))}} }// 普通函数 function print(){ // new 的方式调用 bind 参数输出换做 [...arguments] console.log(this.name); }
// 自定义对象
var obj = { name:'pc' }
/ 调用函数的 call 方法
let F = print.myBind(obj,1,2,3);
// 返回对象
let obj1 = new F();
console.log(obj1);

javascript中this用法相关推荐

  1. JavaScript中foreach()用法及使用的坑

    JavaScript中foreach()用法及使用的坑 JavaScript中foreach是用于遍历数组的方法,将遍历到的元素传递给回调函数,遍历的数组不能是空的要有值. foreach 语法: [ ...

  2. javascript中in用法介绍

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. JavaScript中setAttribute用法详解

    setAttribute基本用法 element.setAttribute(attributename,attributevalue) setAttribute() 方法添加指定的属性,并为其赋指定的 ...

  4. JavaScript中setAttribute用法

    我们经常需要在JavaScript中给Element动态添加各种属性,这可以通过使用setAttribute()来实现,这就涉及到了浏览器的兼容性问题. setAttribute(string nam ...

  5. JavaScript中onload()用法

    实例: 页面加载之后立即执行一段 JavaScript: <html><head><script>function load(){alert("页面已加载 ...

  6. javascript中document用法

    详细讲解JavaScript脚本语言的 document 对象者:整理对象属性 代码 document.title              //设置文档标题等价于HTML的<title> ...

  7. JavaScript中===的用法/编程语言中等号的理解

    等号 = 在编程语言中一般是用于赋值的,这个在初学C语言时曾经困扰了我一阵,只是死记硬背一个等号是赋值,将右边的值赋给左边的变量. 后来接触面向对象的语言时,对等号有了新的理解,等号右边是一个对象,等 ...

  8. javascript 中的innerHTML的用法

    javascript中innerHtml用法 2009-04-21 22:52 <html> <head> <script language="javascri ...

  9. javascript 中 console 的用法

    javascript 中 console 的用法 视频 https://www.bilibili.com/video/BV1g7411L751?from=search&seid=1567656 ...

  10. JavaScript中window.open用法实例详解

    本文较为详细的分析了JavaScript中window.open用法.分享给大家供大家参考.具体如下: 复制代码 代码如下: <script LANGUAGE="javascript& ...

最新文章

  1. 例题5-8 Unixls命令(Unix ls,UVa400)
  2. 测试在MicroPython中对于main.py进行修改
  3. 一个很有意思的问题: 揭示了计算机程序问题的一般处理思路
  4. IT培训分享:学什么语言不愁找工作?
  5. Android内存泄漏总结
  6. android 照片多选,Android: 关于系统相册多选图片的问题
  7. 现代制造工程课堂笔记07——应力应变分析(考点应力莫尔圆)
  8. 关联映射 一对多 实验心得_使用影响映射来帮助您的团队进行实验
  9. ci php做多图上传,CodeIgniter快速实现图片上传
  10. C++_跳转语句continue_跳转语句goto_一维数组数组_数组定义_数组名---C++语言工作笔记019
  11. ios简单sqlite使用
  12. asp.net获取服务器信息
  13. 蔡为东:行之有效的IT技术团队管理实践
  14. 延迟队列DelayQueue研究
  15. 公证电子签名的法律可靠性分析
  16. 基于R语言的层次聚类分析-【案例实操】-基本操作,一看就会
  17. 【android】悬浮球
  18. android 监听锁屏 权限,Android中监听锁屏变化和防止锁屏
  19. 关于NBMA网络基于RIP、HDLC、PPP,MGRE环境下实现所有PC互通
  20. 07 PCA(主成分分析)之梯度上升法

热门文章

  1. linux配置文件前面有分号,linux中的分号 ||
  2. 向量数量积公式_向量数量积公式是什么
  3. 线性代数可以速成吗_怎样速成线性代数?
  4. 航空公司客户价值分析(python)
  5. 运放参数的详细解释和分析-part18,压摆率(SR)
  6. js导出excels表格.XLSX
  7. PostgreSQL数据库——Pigsty
  8. 高可用PgSQL集群架构设计与落地
  9. 5G标准演进过程及个人应用的发展
  10. 旋转的描述【2】——等效旋转矢量与四元数