Note On <You Don't Know JS - this and Object Prototypes>
来源:互联网 发布:百度云mac版怎么加速 编辑:程序博客网 时间:2024/06/17 03:20
Chapter 1
this is not an author-time binding but a runtime binding.
It is contextual based on the conditions of the function's invocation.
this binding has nothing to do with where a function is declared, but has instead everything to do with the manner in which the function is called.
When a function is invoked, an activation record, otherwise known as an execution context, is created. This record contains information about where the function was called from (the call-stack), how the function was invoked, what parameters were passed, etc. One of the properties of this record is the this reference, which will be used for the duration of that function's execution.
Chapter 2
How does the call-site determine where this will point during the execution of a function?
Rule 1: Default Binding
Standalone function invocation, this rule is the default when none of the other rules apply.
function foo() {console.log(this.a);}var a = 2;foo(); // 2
It points this at the global object.
function foo() {console.log( this.a );}var a = 2;(function(){"use strict";foo(); // 2})();
Rule 2: Implicit Binding
In this case, the call-site has a context object.
function foo() {console.log(this.a);}var obj = {a: 2,foo: foo};obj.foo(); // 2
Regardless of whether foo() is initially declared on foo, or is added as a reference later (as this snippet shows), in neither case is the function really "owned" or "contained" by the obj object.
However, the call-site uses the obj context to reference the function, and when there is a context object for a function reference, the implicit binding rule says that it's that object that should be used for the function call's this binding.
Implicitly lost
Implicitly bound function can lose the binding, and it usually falls back to the default binding. It happens when passing a callback function as a parameter.
function foo() {console.log(this.a);}function doFoo(fn) {// `fn` is just another reference to `foo`fn(); // <-- call-site!}var obj = {a: 2,foo: foo};var a = "oops, global"; // `a` also property on global objectdoFoo(obj.foo); // "oops, global"
Rule 3: Explicit Binding
function foo() {console.log(this.a);}var obj = {a: 2};foo.call(obj); // 2
Now you force its this to be obj.
Hard binding
But it doesn't solve implicitly lost. To fix it, you need Hard binding:
function foo() {console.log(this.a);}var obj = {a: 2};var bar = function() {foo.call(obj);};bar(); // 2setTimeout(bar, 100); // 2// hard-bound `bar` can no longer have its `this` overriddenbar.call(window); // 2
No matter how you later invoke the function bar, it will always manually invoke foo with obj. This binding is both explicit and strong, so we call it hard binding.
function foo(something) {console.log(this.a, something);return this.a + something;}var obj = {a: 2};var bar = function() {return foo.apply( obj, arguments );};var b = bar(3); // 2 3console.log(b); // 5
Or you can create a helper:
function foo(something) {console.log(this.a, something);return this.a + something;}// simple `bind` helperfunction bind(fn, obj) {return function() {return fn.apply(obj, arguments);};}var obj = {a: 2};var bar = bind(foo, obj);var b = bar(3); // 2 3console.log(b); // 5
Actually it's provided with a builtin utility as of ES5, Function.prototype.bind, and it's used like this:
function foo(something) {console.log(this.a, something);return this.a + something;}var obj = {a: 2};var bar = foo.bind(obj);var b = bar(3); // 2 3console.log(b); // 5
Rule 4: new Rule
In JS, constructors are just functions that happen to be called with the new operator in front of them. They are not attached to classes, nor are they instantiating a class. They are not even special types of functions. They're just regular functions.
Any ol' function, including the built-in object functions like Number(..) can be called with new in front of it, and that makes that function call a constructor call.
When a function is invoked with new in front of it, the following things are done automatically:
- A brand new object is created (aka constructed) out of thin air.
- The newly constructed object is [[Prototype]]-linked.
- The newly constructed object is set as the this binding for that function call.
- Unless the function returns its own alternate object, the new-invoked function call will automatically return the newly constructed object.
function foo(a) {this.a = a;}var bar = new foo(2);console.log(bar.a); // 2
Precedence of the Rules
- new binding
- explicit binding
- implicit binding
- default binding
new binding vs. explicit binding
function foo(something) { this.a = something;}var obj1 = {};var bar = foo.bind(obj1);bar(2);console.log(obj1.a); // 2var baz = new bar(3);console.log(obj1.a); // 2console.log(baz.a); // 3
new binding vs. implicit binding
function foo(something) { this.a = something;}var obj1 = { foo: foo};var obj2 = {};obj1.foo(2);console.log(obj1.a); // 2obj1.foo.call(obj2, 3);console.log(obj2.a); // 3var bar = new obj1.foo(4);console.log(obj1.a); // 2console.log(bar.a); // 4
explicit binding vs. implicit binding
function foo() { console.log(this.a);}var obj1 = { a: 2, foo: foo};var obj2 = { a: 3, foo: foo};obj1.foo(); // 2obj2.foo(); // 3obj1.foo.call(obj2); // 3obj2.foo.call(obj1); // 2
- Note On <You Don't Know JS - this and Object Prototypes>
- Note On <You Don't Know JS - Scope and Closures>
- 《You Don't Know JS》
- You don't know js
- you don't know js读书笔记
- javascript中的this---you don't know js学习笔记(一)
- 5 Ruby on Rails Tips You Probably Don’t Know
- 其实You Don't Know
- something you don't know
- 读you don't know js 有感之作用域
- You Don't Know JS: Types & Grammar 总结
- You don't have permission to access / on this server
- You don't have permission to access /*** on this server
- You don't have permission to access / on this server.
- You don't have permission to access on this server.
- You don't have permission to access / on this server.
- You don't have permission to access ××× on this server.
- You don't have permission to access / on this server
- imx6 x264 ffmpeg 移植----fwqlzz love is for ever
- mac 下常用命令
- JAVAweb开发技术-------(一)Http协议
- 三级缓存
- AWS存储
- Note On <You Don't Know JS - this and Object Prototypes>
- 积分表
- 如何用在python中迭代一个列表以及字典的索引和值?
- uva1601(The morning after Helloween)解题报告
- c++11之regex:初识regex
- android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context
- 欧拉回路(其实我感觉和欧拉回路没有啥关系,二进制的学习)
- Fresco图片加载框架
- IP地址、网络号、网关的区别