了解完函数的调用区域是如何影响this 对象的,还有this 的各种绑定方式以及各种绑定方式的优先级后

最后一部分,来了解一下this 的一些例外情况

1、被忽略的this

例如在使用bind 方法时候进行函数柯里化,如果此时函数并没有打算绑定任何对象在bind() 方法的第一个参数可以传进一个 null充当占位符

例:

function foo(a,b){

    console.log("a: " + a + "b: " + b);
} var bar = foo.bind(null,3);//在绑定this 对象的同时传入第一个参数 bar(5);//在调用的时候再把第二个参数传进去

tips:
所谓函数柯里化,就是将一堆参数分配内部函数执行,最后再返回所有参数的结果
本人还没对柯里化深入认识只能说一点皮毛

如上例,将函数绑定在一个空对象中 就相等于把函数绑定在了全局环境中
这样做的方法比较危险 于是有了更安全的this 绑定 这一说法
把不需要做任何绑定的函数绑定在一个空对象中(此空对象是我们自己创建的对象)
例如:
通过Object.create(null) 创建一个空对象,这样创建比 {} 这样更空
因为省略了对象的prototype

function foo(a,b){

    console.log("a: " + a + "b: " + b);
} var empty = Object.create(null);//创建一个安全的 不会影响全局作用域的空对象 //把foo 函数绑定在空对象上执行 foo.apply(empty,[2,5]);//"a: " + 2 + "b: " + 5 var fun = foo.bind(empty,6); fun(8);

这样的执行会更加的安全

2、间接引用

间接引用通常会产生在函数引用的赋值上
例:

function foo(){
console.log(this.a);
} var obj1 = {
a: 23333,
foo: foo
} var obj2 = {
a: 6666,
} var a = "window here"; (obj2.foo = obj1.foo)();

注意这里还是那个问题,obj1 虽然是引用着函数foo

但是引用的内容仅仅是函数foo 的引用而已,this对象的绑定还是要看函数在哪里调用
此时函数 foo的调用位置在全局 因此在非严格模式下函数输出全局变量 a
如需绑定对象可以把上面的引用通过硬绑定的方式去执行

书上还写了一个修改函数原型的软绑定方法

    if (!Function.prototype.softBind) {
Function.prototype.softBind = function(obj) {
// 获取当前调用此方法的函数
var fn = this;
// 获取所有 softbind 除第一个以外的所有参数
var curried = [].slice.call( arguments, 1 ); //绑定函数
var bound = function() {
//当bound函数 被执行时 返回调用函数在指定对象的执行效果
//判断如下
return fn.apply(
//如果调用bound函数时 它的this 是指向了window 或者为false
//那么将它绑定在前期调用的绑定对象上
//如果不是
//放在调用它的对象上面执行
(!this || this === (window || global))?
obj : this,
curried.concat.apply(curried, arguments)
);
};
bound.prototype = Object.create(fn.prototype);
//修改bound 函数的原型对象为调用函数的原型 return bound;//返回bound 函数
};
}

这个方法意义在于不允许函数引用全局对象 而且比bind() 函数绑定好的一点是,当绑定完了一个对象时下面还可以绑定其他对象而不会永远地绑定在了一开始绑定的对象上

    function foo(){
console.log("this.name: " + this.name);
} var obj1 = {
name: "obj1"
} var obj2 = {
name: "obj2"
} var obj3 = {
name: "obj3"
} var bar1 = foo.softBind(obj1);//这里通过软绑定 将foo绑定在了obj1 上
bar1();//当全局变量执行时 它的this 便不再指向window而是指向了前期绑定好的obj1 上
//如果通过对象去调用呢?
obj2.bar1 = bar1;
obj2.bar1();//显示为 obj2 了 //再与原来的硬绑定 bind对比
var bar2 = foo.bind(obj1);
bar2();//结果是输出 obj1 obj2.bar2 = bar2;
bar2();//这里结果就不一样了 foo永远绑死在了obj1 上不能再改变了

最后介绍最后一个特殊的函数 es6 的箭头函数()=>
这个函数有一个特点就是 它的this 永远指向包含它的函数的this
看实例就懂

        function baz(){
//继承自baz
return (a)=>{
console.log(this.a);//输出外层函数能访问到的属性名
}
} var o1 = {
a: "o1 here"
} var o2 = {
a: "o2 here"
} var bat = baz.call(o2);
bat.call(o1,"a");//即使箭头函数在o1 内部调用 但是也只会输出baz调用对象的属性

其实在js 高程里面也说过一个问题 匿名函数的this 会指向了window
而es6 的箭头函数正好解决了这个问题 使this 更加完整了
而在es6 语法之前我们还有一个解决方案就是把 外部包含函数的this 对象保存在一个内部函数能够放到的变量上

然后内部函数再通过这个变量调用外部函数能访问的属性即可

this对象的介绍到这里介绍完了 我也要去撸一把特效之类的实际应用了,看太久理论真的会很累

【笔记】探索js 的this 对象 (第三部分)的更多相关文章

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

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

  2. HIbernate学习笔记(二) hibernate对象的三种状态与核心开发接口

    1.在hibernate中持久化对象有三个状态,这个面试时可能会问到: (1)transient瞬时态:在数据库中没有与之匹配的数据,一般就是只new出了这个对象,并且在session缓存中也没有即此 ...

  3. 【笔记】探索js 的this 对象 (第一部分)

    最近在看 你不知道的javascript 这本书,在第二部分看到了一个比较重要的知识点 那就是 this对象的全面认识,于是做一下笔记 博主本人在看这本书之前也一直以为 this 是指一切引用类型的本 ...

  4. 【笔记】探索js 的this 对象 (第二部分)

    了解this 对象之后 我们明白了this 对象就是指向调用函数的作用域 那么接下来我们便要清除函数究竟在哪个作用域调用 找到调用的作用域首先要了解一下几点: 1.调用栈: 调用栈就是一系列的函数,表 ...

  5. HIbernate学习笔记3 之 缓存和 对象的三种状态

    一.hibernate一级缓存 *  hibernate创建每个Session对象时,都会给该Session分配一块独立的缓冲区,用于存放Session查询出来的对象,这个分配给session的缓存区 ...

  6. js高级程序设计(第三版)学习笔记(第一版)

    ecma:欧洲计算机制造商协会iso/iec:国际标准化和国际电工委员会 dom级别(10*)文档对象模型1:DOM核心(映射基于xml文档)与dom html(在dom核心基础上)2:对鼠标,事件, ...

  7. 读书笔记-你不知道的JS上-对象

    好想要对象··· 函数的调用位置不同会造成this绑定对象不同.但是对象到底是什么,为什么要绑定他们呢?(可以可以,我也不太懂) 语法 对象声明有两个形式: 1.字面量 => var obj = ...

  8. 超全面的JavaWeb笔记day03<JS对象&函数>

    1.js的String对象(****) 2.js的Array对象 (****) 3.js的Date对象 (****) 获取当前的月 0-11,想要得到准确的月 +1 获取星期时候,星期日是 0 4.j ...

  9. 5月15日上课笔记-js中 location对象的属性、document对象、js内置对象、Date事件对象、

    location的属性: host: 返回当前主机名和端口号 定时函数: setTimeout( ) setInterval() 二.document对象 getElementById(); 根据ID ...

随机推荐

  1. 利用CSS3伪类做3D按钮

    这是通过css3伪类实现的3d按钮,html代码为: <div id="container_buttons"> <p><a class="a ...

  2. WebDriver自动化测试工具(1)---环境搭建

    Webdriver是一个前端自动化测试工具,可以模拟用户点击链接,填写表单,点击按钮等操作,下面介绍其使用 一.下载WebdriverC#类库以及对应浏览器驱动 http://www.selenium ...

  3. nodejs里的express自动刷新高级篇【转载】

    搬运自[简书:http://www.jianshu.com/p/2f923c8782c8]亲测可用哦! 最近在使用express框架及mongodb,由于前端和后端代码修改后都需要实现自动刷新功能,刚 ...

  4. 最简单的Web Service实现

    概述 这里提供一个最简单的Web Service的实现,基于JAX-WS.除了jdk不需要任何其他jar包,使用Eclipse提供的Web Services Explorer访问服务. 服务端的实现 ...

  5. 【Bzoj3527】【Luogu3338】[Zjoi2014]力(FFT)

    题面 Bzoj Luogu 题解 先来颓柿子 $$ F_i=\sum_{j<i}\frac{q_iq_j}{(i-j)^2}-\sum_{j>i}\frac{q_iq_j}{(i-j)^2 ...

  6. 洛谷——P1626 象棋比赛

    P1626 象棋比赛 题目描述 有N个人要参加国际象棋比赛,该比赛要进行K场对弈.每个人最多参加两场对弈,最少参加零场对弈.每个人都有一个与其他人不相同的等级(用一个正整数来表示). 在对弈中,等级高 ...

  7. 持续获取password

    function GetPasswd { RunCounter=1 DB_PSSWD=getpassword while [ -z "${DB_PSSWD}" -a ${RunCo ...

  8. bytes2HexString

    public static String bytes2HexString(byte[] b) { String r = ""; for (int i = 0; i < b.l ...

  9. 设计模式-组合模式(Composite Pattern)

    本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 前置技能:认识数据结构中的树形结构. 组合模式简介 组合模式是将对象组合成树形结构以表示“部分- ...

  10. .NET分层登陆——机房收费系统再总结

    去年的时候,我写过一篇机房收费系统登陆的总结文章,那是站在VB的基础上,直接查询数据库实现的登陆.是很初期的知识.如果想了解详情,请看VB查询数据库之登陆窗体--机房收费系统总结(一). 今天,我要换 ...