this是什么

this就是函数内部的关键字

看下面例子理解js中的this

    // 例子1
function fnOne () {
console.log(this)
}
'use strict'
function fnOne () {
console.log(this)
}
// 例子2
let a = {
txt: 'hello world',
fn: function() {
console.log(this.txt)
}
}
a.fn()
window.a.fn()
// 例子3
let b = {
txt: 'hello',
obj: {
txt: 'world',
fn: function(){
console.log(this.txt)
console.log(this)
}
}
}
let c = {
txt: 'hello',
obj: {
// txt: 'world',
fn: function(){
console.log(this.txt)
}
}
}
b.obj.fn()
c.obj.fn()
let d = b.obj.fn
d()
    // 例子4
function Fn () {
this.txt = 'hello world'
}
let e = new Fn()
e.txt
// 例子5
function Fn () {
this.txt = 'hello world'
return {txt:'hello'}
}
function Fn () {
this.txt = 'hello world'
return [1]
}
function Fn () {
this.txt = 'hello world'
return 1
}
function Fn () {
this.txt = 'hello world'
return null
}
function Fn () {
this.txt = 'hello world'
return undefined
}
let e = new Fn()
e.txt
// 带有{}或者[]返回值的方法实例化时this指向被改变
    // 例子6
// 箭头函数与包裹它的代码共享相同的this对象
// 如果箭头函数在其他函数的内部
// 它也将共享该函数的arguments变量
let bob = {
_name: "Bob",
_friends: [],
printFriends: () => {
console.log(this._name)
console.log(this)
}
}
let bob = {
_name: "Bob",
_friends: [],
printFriends() {
console.log(this._name)
console.log(this)
}
} let bob = {
_name: "Bob",
_friends: [1],
printFriends() {
this._friends.forEach((item) => {
console.log(this._name)
})
}
}
// arguments 对象
function square() {
let example = () => {
let numbers = [];
for (let number of arguments) {
numbers.push(number * number);
} return numbers;
}; return example();
} square(2, 4, 7.5, 8, 11.5, 21); // returns: [4, 16, 56.25, 64, 132.25, 441]

this的指向

this永远指向的是最后调用它的对象(箭头函数除外)

this的应用

如何改变函数的this指向 apply call bind

三者的区别apply和call改变函数this而且是立即执行。bind(es5新加方法注意兼容性)是复制函数,不会立即执行。根据各自执行时机的不同来选择采用哪种方案。

function Product(name, price) {
this.name = name
this.price = price
}
function Food(name, price) {
Product.call(this, name, price)
// Product.apply(this, arguments)
this.category = 'food'
}
console.log(new Food('cheese', 5).name)

bind用法和可以解决的问题

// 解决,从对象中拿出方法定义给新变量,但是希望方法的this值保持不变这时可以用bind来绑定this
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 返回 81
var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域
// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81 // bind配合setTimeout()
function LateBloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
LateBloomer.prototype.bloom = function() {
window.setTimeout(this.declare.bind(this), 1000);
}
LateBloomer.prototype.declare = function() {
console.log('I am a beautiful flower with ' +
this.petalCount + ' petals!');
}
var flower = new LateBloomer();
flower.bloom(); // 一秒钟后, 调用'declare'方法

箭头函数的this使用注意事项

1、函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
2、不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
3、不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
4、不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
5、不能使用apply/call/bind

// 箭头函数可以让setTimeout里面的this,绑定定义时所在的作用域,而不是指向运行时所在的作用域。下面是另一个例子。
function Timer() {
this.s1 = 0;
this.s2 = 0;
// 箭头函数
setInterval(() => this.s1++, 1000);
// 普通函数
setInterval(function () {
this.s2++;
}, 1000);
} var timer = new Timer(); setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0
// 箭头函数可以让this指向固定化,这种特性很有利于封装回调函数。下面是一个例子,DOM 事件的回调函数封装在一个对象里面。
var handler = {
id: '123456', init: function() {
document.addEventListener('click',
event => this.doSomething(event.type), false);
}, doSomething: function(type) {
console.log('Handling ' + type + ' for ' + this.id);
}
};

如何理解js中的this和实际应用中需要避开哪些坑的更多相关文章

  1. 怎么理解js中的事件委托

    怎么理解js中的事件委托 时间 2015-01-15 00:59:59  SegmentFault 原文  http://segmentfault.com/blog/sunchengli/119000 ...

  2. 如何更好的理解js中的this,分享2段有意思的代码

    关于js中this的浅析,大家可以点击[彻底理解js中this的指向,不必硬背]这篇博客了解. 今天遇到2段比较有意思的代码. ----------------第一段----------------- ...

  3. 【学习笔记】六:面向对象的程序设计——理解JS中的对象属性、创建对象、JS中的继承

    ES中没有类的概念,这也使其对象和其他语言中的对象有所不同,ES中定义对象为:“无序属性的集合,其属性包含基本值.对象或者函数”.现在常用的创建单个对象的方法为对象字面量形式.在常见多个对象时,使用工 ...

  4. 图文结合深入理解JS中的this值

    文章目录 Js 中奇妙的this值 1. 初探this 2. this指向总结 2.1 普通函数调用 2.2 对象的方法调用 2.3 构造函数调用 2.4 利用call,apply,bind方法调用函 ...

  5. 详细理解JS中的继承

    正式说继承之前,有两个相关小点: JS只支持实现继承,即继承实际的方法,不支持接口继承(即继承方法的签名,但JS中函数没签名) 所有对象都继承了Object.prototype上的属性和方法. 说继承 ...

  6. 图文结合深入理解 JS 中的 this 值

    图文结合深入理解 JS 中的 this 值 在 JS 中最常见的莫过于函数了,在函数(方法)中 this 的出现频率特别高,那么 this 到底是什么呢,今天就和大家一起学习总结一下 JS 中的 th ...

  7. 深度理解js中var let const 区别

    首先要理解js中作用域的概念 作用域:指的是一个变量的作用范围 1.全局作用域 直接写在script中的js代码,在js中,万物皆对象,都在全局作用域,全局作用域在页面打开时创建,在全局作用域中有一个 ...

  8. 深入理解JS中的对象(二):new 的工作原理

    目录 序言 不同返回值的构造函数 深入 new 调用函数原理 总结 参考 1.序言 在 深入理解JS中的对象(一):原型.原型链和构造函数 中,我们分析了JS中是否一切皆对象以及对象的原型.原型链和构 ...

  9. 深入理解JS中的对象(三):class 的工作原理

    目录 序言 class 是一个特殊的函数 class 的工作原理 class 继承的原型链关系 参考 1.序言 ECMAScript 2015(ES6) 中引入的 JavaScript 类实质上是 J ...

随机推荐

  1. iMX6Q/PLUS开发板烧写设备树内核的Ubuntu系统

    基于迅为-iMX6D.iMX6Q 和 iMX6PLUS 三个硬件版本,设备树镜像的烧写方法以及镜像所在目录,镜像名称全部一致,所以作者将烧写章节合并到一起. 请注意,如果购买的是 iMX6D 版本,想 ...

  2. 401认证钓鱼demo

    <?php //@b4dboy if(!isset($_SERVER['PHP_AUTH_USER']) && !isset($_SERVER['PHP_AUTH_PW'])) ...

  3. 二分法C++与Python

    来源于Leetcode C++ int binarySearch(vector<int>& nums, int target){ if(nums.size() == 0) retu ...

  4. scala编程(六)——函数式对象

    Rational 的式样书 分数:rational number 是一种可以表达为比率 d n 的数字,这里的 n 和 d 是数字,其中 d 不能为零.n 被称作是分子:numerator,d 被称作 ...

  5. Introduction to Differential Equations,Michael E.Taylor,Page 3,4 注记

    此文是对 [Introduction to Differential Equations,Michael E.Taylor] 第3页的一个注记.在该页中,作者给了微分方程$$\frac{dx}{dt} ...

  6. centos7 部署vue项目(前后端分离、nginx)

    一.环境准备 1.centos7系统 2.mysql数据库 3.在centos7虚拟机上安装好nginx 二.部署内容准备 1.后端war包 或者可执行jar 因为我这里是spring boot项目. ...

  7. spring mvc 页面form提示语

    <form:form id="inputForm" modelAttribute="bsRabiesNum" action="${ctx}/nu ...

  8. xpath-helper使用

    xpath-helper提取不到frame元素时: https://blog.csdn.net/skywinne/article/details/83832126

  9. java第二节课 java语法基础动手动脑

    动手动脑1:枚举变量   运行EnumTest.java package test2; public class EnumTest {  public static void main(String[ ...

  10. git 第一次上传本地代码到远程仓库,解决 ! [rejected] master -> master (non-fast-forward)错误

    使用git想GitHub远程仓库上传代码的基本步骤一般是 初始化为git仓库 git init 添加所有要提交的文件 git add . 本次提交说明 git commit -m '提交说明' 关联G ...