了解完函数的调用区域是如何影响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. 通过百度地图API获取经纬度以及两点间距离

    package com.baidumap; import java.io.BufferedReader; import java.io.IOException; import java.io.Inpu ...

  2. office2007/2010/2013输入公式的正确方式

    博客中的文章均为 meelo 原创,请务必以链接形式注明本文地址 理工科的学生,写报告.写论文那面需要输入公式,过去大家常用的公式编辑器是mathtype,虽然功能强大,但输入极为不方便,输入个指数. ...

  3. ajax在提交url时候遇到的编码问题

    //escape()不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值.比如"春节"的返回结果是%u6625%u8282,escape()不对"+& ...

  4. RHEL7删除yum命令后如何恢复

    楼主也是不小心删除了rhel7上的yum命令,后来通过安装centos7的yum命令解决 1.首先下载yum相关的rpm包 http://mirrors.163.com/centos/7/os/x86 ...

  5. BotFramework Nodejs示例

    关于Bot Framework知识,可以参考<Nodejs Bot学习> 本文是根据bot framework sample<https://github.com/Microsoft ...

  6. thinkphp join 表前缀

    public function get_user_group_title($uid){ $pre = C('DB_PREFIX'); $res = M('AuthGroupAccess aga')-& ...

  7. Luogu P4148 简单题(K-D Tree)

    题面 题解 因为强制在线,所以我们不能$cdq$分治,所以考虑用$KDT$,$KDT$维护一个矩阵,然后询问的时候如果当前矩形在询问区间内,直接记贡献,否则判断当前点是否在矩阵内,然后左右分别递归下去 ...

  8. 洛谷——P1618 三连击(升级版)

    P1618 三连击(升级版) 题目描述 将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数的比例是A:B:C,试求出所有满足条件的三个三位数,若无解,输出“No!!!”. //感谢 ...

  9. Codeforces Round #307 (Div. 2) E. GukiZ and GukiZiana(分块)

    E. GukiZ and GukiZiana time limit per test 10 seconds memory limit per test 256 megabytes input stan ...

  10. ARM开发板不工作的几个原因

    刚焊了5块ARM(LPC2478)的开发板,上程序测试了一下,发现只有一个板子工作其他四个全部歇菜.努力地找了一会最终发现是板子的来个电阻焊翻了.因为是1206 的封装而且来个电阻在PCB上摆放的位置 ...