企业网站系统cms,做网站技术要求怎么写,wordpress电子邮件怎么设置,2008iis 网站 打不开this指向参考文章#xff1a;* thisJavaScript中this指向分为以下几种情况#xff1a;普通函数或作为对象属性事件绑定构造函数箭头函数call/apply/bind指定下面我们来进行一一介绍普通函数或作为对象属性this取决于方法执行前面是否有“点”#xff0c;有“点”的话#x…this指向参考文章 * thisJavaScript中this指向分为以下几种情况普通函数或作为对象属性事件绑定构造函数箭头函数call/apply/bind指定下面我们来进行一一介绍普通函数或作为对象属性this取决于方法执行前面是否有“点”有“点”的话“点”前面是谁this就是谁如果没有点的话this指向windowconst fn function () {console.log(this);
};const obj { name: OBJ, fn };fn();obj.fn();const fn1 obj.fn;
fn1();
answer:1. window
2. {name: OBJ, fn: function() {console.log(this)}} // obj
3. window可以看到函数作为对象的属性被调用的时候其this指向调用该函数的对象否则其this指向window事件绑定在进行事件绑定的时候事件绑定函数中的this是绑定事件的元素// 假设页面中有id为button的button元素
// var x 100;
window.x 100;
const fn function () {console.log(this.x);
};
const obj { x: 200, fn };
const $button document.getElementById(button);
$button.x 300;obj.fn();
const fn1 obj.fn;
fn1();$button.addEventListener(click, fn);
$button.addEventListener(mouseenter, obj.fn);$button.addEventListener(mouseleave, function () {obj.fn();});
answer:1. 200
2. 100
3. 点击button时300
4. 鼠标移入button时300
5. 鼠标移出时200但是需要注意的是这里我们是在用户点击时浏览器帮我们将点击事件的this指向绑定该事件的DOM元素。如果通过代码来触发对应的事件的话我们可以通过call/apply/bind来指定其this$button.click.call() // this为window,打印结果为100
构造函数(new Fn)构造函数(new Fn)执行函数中的this是当前类的实例这是new关键字帮我们做到的: var x 100;
const Fn function () {this.x 200;console.log(this.x);
};const fn new Fn();
answer: 1. 200箭头函数箭头函数中没有自身的this所用到的this都是其最近父级上下文中的thisconst fn function () {console.log(this);setTimeout(() {console.log(this);}, 1000);setTimeout(function () {console.log(this);});
};const obj { x: 100, fn };obj.fn();
answer:1. {x:100, fn: function() {...}} // obj
2. window
3. {x:100, fn: function() {...}} // objcall/apply/bind改变this指向为call/apply/bind传入的第一个参数即为函数的this var x 100;
const obj { x: 200, y: 200 };
const fn function () {console.log(this.x);
};fn();
fn.call(obj);
fn.apply(obj);const fixedThisFn fn.bind(obj);
fixedThisFn();
answer:1. 100
2. 200
3. 200
4. 200call在执行时第一个参数为this指向之后的参数为fn执行时的参数apply在执行时第一个参数为this指向之后的参数为fn执行时的参数组成的数组数组的每一项会和fn的每一个参数进行对应bind在执行时第一个参数为预先传入this指向之后的参数为实际调用fn前预先传入的参数返回值为一个函数fixedThisFnfixedThisFn内部会调用fn并指定其this指向为了更深入的理解call/apply/bind是如何改变函数中this指向的下面我们分别模拟实现这三个函数call/apply/bind源码实现根据前面的介绍我们知道当函数作为对象属性被调用时this指向调用该函数的对象const obj { x: 100, fn () {console.log(this);} };
obj.fn(); // {x: 100, fn: function() {...}} obj
利用JavaScript这个特性我们可以将执行的函数作为call/apply的第一个参数context的属性然后通过context来调用该属性对应的函数函数的this便指向了contextcall的源码模拟如下Function.prototype.myOwnCall function (context, ...args) {const uniqueKey new Date().getTime();// this为调用call方法的函数context[uniqueKey] this;// 作为对象的方法被对象调用this指向该对象contextconst result context[uniqueKey](...args);delete context[uniqueKey];return result;
};
到这里有的小伙伴可能已经发现了如果call/apply传入的context不是对象呢首先我们看下mdn对call方法的第一个参数的描述语法function.call(thisArg, arg1, arg2, ...) * thisArg 可选的。在function函数运行时使用的this值。请注意this可能不是该方法看到的实际值如果这个函数处于非严格模式下则指定null或undefined时会自动替换为指向全局对象原始值会被包装接下来我们对myOwnCall方法的第一个参数做如下处理function translateToObject (context) {// 可以通过 进行判断 context null// null undefined 2个等号是成立的// null,undefined windowif (typeof context undefined || context null) {context window;} else if (typeof context number) { // 原始值转换为包装对象context new Number(context);} else if (typeof context string) {context new String(context);} else if (typeof context boolean) {context new Boolean(context);}return context;
}
在myOwnCall方法中调用该函数Function.prototype.myOwnCall function (context, ...args) {context translateToObject(context);const uniqueKey new Date().getTime();// this为调用call方法的函数context[uniqueKey] this;// 作为对象的方法被对象调用this指向该对象contextconst result context[uniqueKey](...args);delete context[uniqueKey];return result;
};
apply的实现与call基本相同只不过第二个参数是一个数组Function.prototype.myOwnBind function (context, paramsArray) {context translateToObject(context);const uniqueKey new Date().getTime();// this为调用call方法的函数context[uniqueKey] this;// 作为对象的方法被对象调用this指向该对象contextconst result context[uniqueKey](...paramsArray);delete context[uniqueKey];return result;
};
相比于call/applybind函数并没有立即执行函数而是预先传入函数执行时的this和参数并且返回一个函数在返回的函数中执行调用bind函数并将预先传入的this和参数传入bind的源码模拟Function.prototype.myOwnBind function (context, ...outerArgs) {const fn this;return function (...innerArgs) {return fn.call(context, ...outerArgs, ...innerArgs);};
};
精简版如下Function.prototype.myOwnBind (context, ...outerArgs) (...innerArgs) this.call(context, ...outerArgs, ...innerArgs);
这里并没有实现通过new操作符来执行fn.bind(context)的操作如果想知道其详细的实现过程可以看我的这篇文章: JS进阶-手写bind在深入理解call/apply/bind的实现原理后我们尝试完成下面的测试function fn1 () {console.log(1);}
function fn2 () {console.log(2);}
fn1.call(fn2);fn1.call.call(fn2);Function.prototype.call(fn1);
Function.prototype.call.call(fn1);
answer:1. 1
2. 2
3. 什么都不输出
4. 1这里我们根据call的源码来进行推导一下Function.prototype.call.call(fn1)其它的执行过程类似// 1. 首先会将Function.prototype.call作为一个函数来执行它原型上的call方法
// 所以call方法内部
// this Function.prototype.call
// context fn1
// 通过对象的属性来执行方法改变this指向
// fn1[uniqueKey] this(Function.prototype.call)
// fn1[uniqueKey]() // 执行 Function.prototype.call方法但是this是context
// 2. 在this为fn1的情况下执行Function.prototype.call方法
// 所以call方法内部
// this fn1
// context window
// 通过对象的属性来改变this指向
// window[uniqueKey] fn1
// window[uniqueKey]() // 执行fn1()但是this是window
这里就是有笔者关于JavaScript中this指向的相关内容的理解希望能对阅读的小伙伴有所帮助