掌握JavaScript基础--理解this关键字的新思路

普通函数

下面这种就是普通函数

function add(x, y) {
    return x + y;
}

每个普通函数被调用的时候,都相当于有一个this参数传进来。

内部函数this不会是外部函数传入的this,相当于和外部的this隔离开了。

function outer() {
    function inner() {
        console.log(this); // window
    }
    console.log(this); // ‘outer‘
    inner();
}
outer.call(‘outer‘);

相当于:

function outer(_this) {
    function inner(_this) {
        console.log(_this); // undefined
    }
    console.log(_this); // ‘outer‘
    inner(undefined);
}
outer(‘outer‘);

箭头函数

const add = (x, y) => {
    return x + y;
};

如果你用箭头函数,内部函数的this和外部是一致的:

function outer() {
    const inner = () => {
        console.log(this); // ‘outer‘
    };
    console.log(this); // ‘outer‘
    inner();
}
outer.call(‘outer‘);

箭头函数的this不会被call方法影响,它总是和箭头函数所在的位置有关:

它所在的位置(也就是作用域)的this指向谁,箭头函数里面的this就指向谁。

function ordinary() {
    const arrow = () => this;
    console.log(arrow.call(‘goodbye‘)); // ‘hello‘
}
ordinary.call(‘hello‘);

普通函数作为方法

如果一个函数赋值给了属性,就变成了方法:

const obj = {
    prop: function () {}
};

调用方法的方式是:

obj.prop(x, y)

相当于:

obj.prop.call(obj, x, y)

陷阱

1 回调函数里面用this

回调里面执行(A),你发现logStatus访问不了。这个是因为this被阻隔了。

performCleanup() {
    cleanupAsync()
    .then(function () {
        this.logStatus(‘Done‘); // (A)
    });
}

你应该采用箭头函数:

performCleanup() {
    cleanupAsync()
    .then(() => {
        this.logStatus(‘Done‘);
    });
}

2 map方法里面用this

同理,this也是访问不了company和name的

prefixNames(names) {
    return names.map(function (name) {
        return this.company + ‘: ‘ + name; // (A)
    });
}

采用箭头函数:

// Inside a class or an object literal:
prefixNames(names) {
    return names.map(
        name => this.company + ‘: ‘ + name);
}

3 用函数作为回调

class UiComponent {
    constructor(name) {
        this.name = name;
        const button = document.getElementById(‘myButton‘);
        button.addEventListener(‘click‘, this.handleClick); // (A)
    }
    handleClick() {
        console.log(‘Clicked ‘+this.name); // (B)
    }
}

改为:

class UiComponent {
    constructor(name) {
        this.name = name;
        const button = document.getElementById(‘myButton‘);
        button.addEventListener(
            ‘click‘, this.handleClick.bind(this)); // (A)
    }
    handleClick() {
        console.log(‘Clicked ‘+this.name);
    }
}

bind函数能让普通的函数调用无法修改this:

function returnThis() {
    return this;
}
const bound = returnThis.bind(‘hello‘);
bound(); // ‘hello‘
bound.call(undefined); // ‘hello‘

保持正确的做法

1 用ESlint的rules: no-invalid-this

避免普通函数内部有this,一般在方法内使用this或者箭头函数内使用

2 不要把this当做参数

因为这样你就不能用箭头函数了

beforeEach(function () {
    this.addMatchers({ // access API object
        toBeInRange: function (start, end) {
            ···
        }
    });
});

可以很容易被改写:

beforeEach(api => {
    api.addMatchers({
        toBeInRange(start, end) {
            ···
        }
    });
});

原文链接:http://2ality.com/2017/12/alternate-this.html

作者知乎/公众号:前端疯 (一群热爱前端的一线程序员维护,想要用前端改变世界。)

来自为知笔记(Wiz)

原文地址:https://www.cnblogs.com/xunxing/p/8683391.html

时间: 2024-10-17 12:23:24

掌握JavaScript基础--理解this关键字的新思路的相关文章

javascript基础 之 保留关键字

1,保留关键字 意思是:特定的字符串要么是已经有指代了要么是未来将要有指代,所以取名字不要用保留关键字里的字符串 js保留关键字 abstract arguments boolean break byte case catch char class* const continue debugger default delete do double else enum* eval export* extends* false final finally float for function got

转载 深入理解JavaScript中的this关键字

转载原地址: http://www.cnblogs.com/rainman/archive/2009/05/03/1448392.html 深入理解JavaScript中的this关键字 1. 一般用处 2. this.x 与 apply().call() 3. 无意义(诡异)的this用处 4. 事件监听函数中的this 5. 总结 在JavaScript中this变量是一个令人难以摸清的关键字,this可谓是非常强大,充分了解this的相关知识有助于我们在编写面向对象的JavaScript程

理解javascript中的with关键字

说起js中的with关键字,很多小伙伴们的第一印象可能就是with关键字的作用在于改变作用域,然后最关键的一点是不推荐使用with关键字.听到不推荐with关键字后,我们很多人都会忽略掉with关键字,认为不要去管它用它就可以了.但是有时候,我们在看一些代码或者面试题的时候,其中会有with关键字的相关问题,很多坑是你没接触过的,所以还是有必要说说with这一个关键字. 一.基本说明 在js高级程序设计中是这样描述with关键字的:with语句的作用是将代码的作用域设置到一个特定的作用域中,基本

【JavaScript基础】------有待完善

最近开始学习JavaScript,整理了一些相关的基础知识,日后继续完善~~~ JS注释方式:// 单行注释(Ctrl+/ )/* 段落注释(Ctrl+shift+/ )*/ JavaScript基础JavaScript:基于浏览器 .基于(面向)对象.事件驱动.脚本语言JavaScript的作用:表单验证,减轻服务的压力,添加页面动画效果,动态更改页面内容,Ajax网络请求(Ajax:可以实现页面局部刷新)JavaScript组成部分:ECMAScript(5.1/6).DOM.BOMECMA

Javascript基础篇小结

Javascript基础篇小结 字数9973 阅读3975 评论7 喜欢28 转载请声明出处 博客原文 随手翻阅以前的学习笔记,顺便整理一下放在这里,方便自己复习,也希望你有也有帮助吧 第一课时 入门基础 知识点: 操作系统就是个应用程序 只要是应用程序都要占用物理内存 浏览器本身也是一个应用程序 浏览器本身只懂得解析HTML 调用浏览器这个应用程序的一个功能绘制 1.javascript介绍 JavaScript操作DOM的本质是=获取+触发+改变 目的:就是用来操作内存中的DOM节点 修改D

JavaScript基础—插曲

Javascript基础 1:js中我们最好使用单引号,其实可以使用双引号的但是为了区别所以js中全部使用单引号.注释和C#的是一样的.网页里面的执行顺序是从上到下依次执行的,不管你js放到哪里,都会按照顺序进行执行的.若是js中出现了错误,只是不继续执行此js中<script></script>的代码,但是网页中其余的js代码还是会执行的. 2:书写js代码的时候我们必须为其加上分号,这样的好处有二:1,可以便于压缩:2,提高了代码的可读性,可维护性. 3:js中的数据类型. 我

JavaScript基础–闭包

JavaScript基础–闭包 理解闭包的概念对于学习JavaScript至关重要,很多新手(包括我)开始学习闭包时,都会感觉似懂非懂,之前看了一些资料,整理了闭包的一篇博客,若有疏忽与错误,希望大家多多给意见. 概述 理解闭包的概念前,建议大家先回想一下JS作用域的相关知识,如果有疑问的同学,可以参考:JavaScript基础–作用域.闭包的定义如下: Closure is when a function is able to remember and access its lexical s

【javascript基础】1、基本概念

原文:[javascript基础]1.基本概念 前言 最近迷茫了一段时间,不知道应该从何处开始学习前端知识,好像这种状态已经持续了一年了,天天也在看前端的东西,但是记住的多少或者说在脑中一团糟,没有什么清晰的概念.最近加入了jQuery源码交流群( 239147101),虽然有时候在群里不说话,或者在里面扯扯淡,在里面学到了不少知识,群主Aaron是个好人,叶小钗是个牛人,告诉我要坚持写博客,谢谢群里的哥们们.感觉刚开始写无从下手,希望以后越来越好,大家尽量给我提意见哈. PS:23914710

【javascript基础】5、创建对象

原文:[javascript基础]5.创建对象 前言 今天从家里回到了学校,在家呆了十天,胖了几斤的重量,又折腾回学校了,春节回家真是艰辛的路途.随便扯扯我的往返行程:为了省钱我没有选择直飞到长春往返都是到北京转的,这样我和女朋友可以节省4000块左右.1月24号深圳-飞机-北京(飞机晚点1个小时),到北京已经凌晨两点多,机场大巴就剩两个了,做一个大巴到了市里在打的到同学那100块没了,到同学那(天通苑附近)都三点了,吃饭喝酒(一瓶牛栏山+2瓶啤酒)到了五点,睡觉到十点,起床去打了两个小时的篮球