函数的this指向谁,和函数在哪里被定义的,函数在哪里被执行的没有半毛钱关系,只遵守下面的规律:

在非严格模式中:

1、自执行函数里面,this永远指向window;

    <script>
var a = 1;
var o = {
a: 2,
fn: (function(){ //自执行函数,在定义的时候就已经执行啦
console.log('自执行函数里面是window',this.a); //自执行函数里面的this指向的是window
return function() { // 但是这里的this 指向的是谁调用的这个函数
console.log('但是还是要具体问题具体分析',this.a)
}
})()
} o.fn();
</script>

结果请看

2、给元素的某一个行为绑定方法,当行为触发所调用的函数里面this指向的该dom 元素;

    <script>
var dd = document.getElementById('dd');
function f1 () {
console.log(this);
}
dd.onclick=f1; // 点击的那个dom对象
</script>

但是我要是稍微改一下:

    <script>
var dd=document.getElementById('dd');
function fn () {
console.log(this);
}
dd.onclick=function(){
console.log(this); // dom 对象
fn(); // window ,这时候就看该函数是被谁调用的啦
}
</script>

3、看看函数执行有咩有 . ,如果有则是前面的那个,如果没有则是window

4、在构造函数里面,this 指向的是当前的实例;

<script>

       function fn() {
console.log(this);
};
function ff () {
this.name="杜俊成";
this.say=function(){
console.log(this); // this指向该构造函数的原型
fn() // window ,因为fn 函数的直接调用者是window,
}
} var a = new ff();
a.say();
</script>

 5、使用call / apply 改变了this 的指向;(关于call 和 apply 想一劳永逸的搞明白吗?请看我的一篇文章)

严格模式:

1、自执行函数里面,this永远指向undefined;

    <script>
var obj ={
fn:(function(){
// this => undefined
console.log(this)
return function(){
// this=> obk
console.log(this);
}
})()
}
obj.fn; //obj.fn 的方法在声明的时候就已经被执行了, window
obj.fn(); //obj.fn的自执行方法返回的方法执行 obj
</script>

2、看前面有咩有 . ,如果有则是前面的那个,如果没有则是undefined

总结就是:严格模式和非严格模式的区别:当调用主体不明时,严格模式是undefined,非严格模式是window

<script>
'use strict';
function fn(){
alert(this);
}
/*非严格模式*/
fn.call()//this - window;
fn.call(null)//this - window;
fn.call(undefined);//this -undefined
/*严格模式下,给call或apply第一个参数传谁this就是谁,不传就是undefined*/
fn.call() //this - undefined;
fn.call(null) //this -null;
fn.call(undefined) //this-undefined
</script>
es6 新增的箭头函数比较特殊。我们使用function定义的函数,在定义时,它并不知道这个this会指向哪里,只有在运行的时候才能明确this的值。
 
箭头函数本身不具有this,它会直接绑定到它的词法作用域内的this,也就是定义它时的作用域内的this值。所以试图使用apply,call等方法修改箭头函数的this是不会成功的,因为箭头函数自身没有this。所以我们来看下面一段代码:
var func = () => {
console.log(this);
}
func(); // Window
func.apply({}); // Window
function func() {
console.log(this)
return () => {console.log(this)}
};
func()()
// Window
// Window
func.apply({a:1})()
// Object {a:1}
// Object {a:1}
func.apply({a:2})()
// Object {a:2}
// Object {a:2}

通过这段代码,我们应该可以明确的看出来,箭头函数是直接使用的它词法作用域内的this,也就是定义它时的作用域内的this。当我们修改它的作用域内的this值,也就是func的this值时,在箭头函数内也可以反映出来。用作对比,我们看下使用function定义的函数:

function func() {
console.log(this)
return function(){
console.log(this)
}
};
func()() //window window
func.apply({a:1})() // {a:1} window
func.apply({a:2})() // {a:2} window

github地址:https://github.com/dujuncheng

十分钟彻底理解javascript 的 this指向,不懂请砸店的更多相关文章

  1. [转帖]十分钟快速理解DPI和PPI,不再傻傻分不清!

    十分钟快速理解DPI和PPI,不再傻傻分不清! https://baijiahao.baidu.com/s?id=1605834796518990333&wfr=spider&for= ...

  2. 十分钟读懂JavaScript原型和原型链

    原型(prototype)这个词来自拉丁文的词proto,意谓“最初的”,意义是形式或模型.在JavaScript中,原型的探索也有很多有趣的地方,接下来跟随我的脚步去看看吧. 原型对象释义 每一个构 ...

  3. 深入理解JavaScript的this指向问题

    Javascript的this用法 this是Javascript语言的一个关键字.它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.比如: function test(){ this.x ...

  4. 图解javascript中this指向

    JavaScript 是一种脚本语言,支持函数式编程.闭包.基于原型的继承等高级功能.JavaScript一开始看起来感觉会很容易入门,但是随着使用的深入,你会发JavaScript其实很难掌握,有些 ...

  5. javascript的this指向

    JavaScript 是一种脚本语言,支持函数式编程.闭包.基于原型的继承等高级功能.JavaScript一开始看起来感觉会很容易入门,但是随着使用的深入,你会发现JavaScript其实很难掌握,有 ...

  6. 十分钟理解JavaScript引擎的执行机制

    关注专栏写文章 十分钟理解JavaScript引擎的执行机制 方伟景 千锋前端开发推动市场提升的学习研究者. 4 人赞同了该文章 首先,请牢记2点: JS是单线程语言 JS的Event Loop是JS ...

  7. 后端技术杂谈11:十分钟理解Kubernetes核心概念

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 本文转自 https://github.com/h2pl/Java-Tutorial 喜欢的 ...

  8. 十分钟理解Java中的动态代理

    十分钟理解 Java 中的动态代理   一.概述 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道 ...

  9. 第一百二十九节,JavaScript,理解JavaScript库

    JavaScript,理解JavaScript库 学习要点: 1.项目介绍 2.理解JavaScript库 3.创建基础库 从本章,我们来用之前的基础知识来写一个项目,用以巩固之前所学.那么,每个项目 ...

随机推荐

  1. Omi v1.0震撼发布 - 令人窒息的Web组件化框架

    原文链接--https://github.com/AlloyTeam/omi 写在前面 Omi框架经过几十个版本的迭代,越来越简便易用和强大. 经过周末的连续通宵加班加点,Omi v1.0版本终于问世 ...

  2. USB PE

    To put WinPE on a USB Stick, you must first make it bootable. Warning: This will destroy all the dat ...

  3. node.js 基础知识之 querystring.stringify querystring.escape

    序列化   1.  querystring.stringify({name:'chenshuai',ago:21,job:"web"})    'name=chenshuai&am ...

  4. 技术方案:在外部网址调试本地js(基于fiddler)

    1 解决的问题 1)        场景1:生产环境报错 对前台开发来说,业务逻辑都在js中,所以报错90%以上都是js问题. 如果生产环境出现报错,但是测试环境正常.这时修改了代码没有环境验证效果, ...

  5. 一名合格的JAVA程序员需要点亮那些技能树?

    这是从450家企业的招聘信息中统计而来,相对来说还是比较真实的,虽然有些公司的招聘要求万年不变,但还是可以大致反应企业的招聘要求的. 尽管Struts2漏洞频出,但是由于政府.银行以及传统企业遗留项目 ...

  6. java学习笔记 --- 异常

    异常 (1)程序出现的不正常的情况. (2)异常的体系   Throwable    |--Error  错误,严重问题,我们不处理.    ·    |--Exception 异常     |--R ...

  7. python服务器环境搭建(3)——参数配置

    前面我们已安装好了python服务器运行所需要的相关软件,而最重要最繁琐的就是参数配置,写这篇就踩了好多坑,花了好多时间,遇到了各种各样的问题.好了费话少说,直接进入本篇话题. PS:本人不是专业的运 ...

  8. 记一次搭建SS服务器,完整的过程。

    前言 这几天为了登录外网查询资料,谷歌经常抽风,国外的博客也打不开,都要整崩溃了.我以前(直到昨天以前)都是使用修改hosts来访问外网的,用的是 老D(https://laod.cn/hosts)  ...

  9. 前端总结·基础篇·JS(四)异步请求及跨域方案

    前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...

  10. Visual Studio Code 使用Chrome Debug 代码

    一.添加插件 Debugger for Chrome,点击安装,安装完成之后,启动 二.配置启动参数 1.按 F5,出现界面如图,选择 Chrome 2.然后会打开配置文件 launch.json 3 ...