问题1: apply、call 、bind有什么作用,什么区别
apply ,call,bind都会改变函数的执行上下文,就是改变函数的this指向。
apply和call都是不会改变原函数,但是参数不一样apply的参数是数组。
bind是会创建一个新的函数,当被调用的时候,this还是指向bind()的第一个参数。而且这个新函数再次使用call或apply时失效。
从apply,bind,call的使用可以从以下代码思路出发:
var obj = {
x: 81,
getX: function() {
return this.x;
}
};
alert(obj.getX.bind(obj)());
alert(obj.getX.call(obj));
alert(obj.getX.apply(obj));
var age=19;
var k={
age:18,
f:function (){
return this.age;
}
}
var p={
age:39
}
var f2=k.f.bind(p);
console.log(f2());//39,this指向的是p
console.log(f2.call(window));//39,因为bind()创建的函数的this还是指向之前bind()第一个参数p,this始终不变
console.log(f2.apply(k));//39,因为bind()创建的函数的this还是指向之前bind()第一个参数p,this始终不变
var f3=k.f.call(window);
console.log(f3());//error,因为call无法产生一个新的函数
问题2: 以下代码输出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()
输出的是John
可以这么思考 john.sayHi().call(john);
问题3: 下面代码输出什么,为什么
func()
function func() {
alert(this)
}
输出的是window
思考:func().call(window);this 就是call函数的参数。
问题4:下面代码输出什么
document.addEventListener('click', function(e){
console.log(this);
setTimeout(function(){
console.log(this);
}, 200);
}, false);
执行结果:
console.log(this)输出的是 document
而setTimeout种输出的console.log(this)
输出是window
因为setTimeout的this无论在哪个位置指向的都是window
问题5:下面代码输出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)
输出的结果是:
John 因为func.call(john)中将this改为了指向john对象
问题6: 以下代码有什么问题,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么
this.showMsg();
})
},
showMsg: function(){
console.log('饥人谷');
}
}
问题是this.showMsg()中this的指向问题
修改如下:
$btn=$("button");
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this);
this.showMsg();
}.bind(this))
},
showMsg: function(){
console.log('饥人谷');
}
}
module.showMsg();
https://jsbin.com/dazigurisi/5/edit?html,js,console,output
总结this的使用:
大部分的函数调用都将call方法省略了,而call的理解就如同一个对象调用一个方法,而this则是只call的第一个参数。
修改setTImeout或者setInterval的this用bind的方法
网址为:https://stackoverflow.com/questions/11366643/how-do-i-change-scope-of-this-in-setinterval-and-settimeout-functions
修改click的this指向用bind方法如下: image.png
网址为:https://stackoverflow.com/questions/5490448/how-do-i-pass-the-this-context-into-an-event-handler
一篇方方介绍了JS 里为什么会有 this
原型链相关问题
方方的一篇关于new 到底是干什么的
https://zhuanlan.zhihu.com/p/23987456
解释:关于new到底是干什么的,我在方方的一篇文章中找到了以下观点:
不用创建临时对象,因为 new 会帮你做(你使用「this」就可以访问到临时对象);
不用绑定原型,因为 new 会帮你做(new 为了知道原型在哪,所以指定原型的名字为 prototype);
不用 return 临时对象,因为 new 会帮你做;
不要给原型想名字了,因为 new 指定名字为 prototype。
总结下来就是new其实就是返回了一个对象,这个对象在new的过程中自动创建了一个_ _proto _ 属性,这个对象中会复制构造函数自己所拥有的内容。同时 _proto _ _这个属性会指向构造函数的原型对象。
问题7:有如下代码,解释Person、 prototype、proto、p、constructor之间的关联。
function Person(name){
this.name = name;
}
Person.prototype.sayName = function(){
console.log('My name is :' + this.name);
}
var p = new Person("若愚")
p.sayName();
image.png
关系为:
p._ _ proto _ _ ==Peroson.prototype ;
Person.prototype.constructor ==Person;
p.__ proto__.constructor==Person;
Person.prototype.__ proto __ ==Object.prototype;
p. __ proto__.__ proto __ ==Object.prototype;
p. __ proto__.__ proto __ ==Person.prototype.__ proto __;
Object. __ proto __ =null;
问题8: 上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链。
image.pngtoSting()是object.prototype中的
P先从proto中查找是否有toString()方法,如果没有就从p.proto.proto中查找,一直沿着原型链查找,直到object的prototype中找到toString方法
问题9:对String做扩展,实现如下方式获取字符串中频率最高的字符
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次
代码如下:
var str = 'ahbbccdeddddfg';
String.prototype.getMostOften=function()
{
var str={};
var key;
for(var i=0;i<this.length;i++)
{
key=this[i];
if(str[key])
{
str[key]++;
}
else
{
str[key]=1;
}
}
var max=0,maxkey;
for(var key in str)
{
if(str[key]>max)
{
max=str[key];
maxkey=key;
}
}
return ("出现最多的字符是:"+maxkey+","+"共出现了"+max+"次");
}
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次
image.png
问题10: instanceof有什么作用?内部逻辑是如何实现的?
instanceof操作符判断一个对象是不是某个类的实例
instanceof依据原型链上的 _ proto _属性指向了构造函数的prototype
function _instanceof(fn,fn2)
{
var pointer=fn.__proto__;
while(pointer)
{
if(pointer==fn2.prototype)
{
return true;
}
else
{
pointer=pointer.__proto__;
}
}
return false;
}
var arr=[1,2];
var fn2=Object;
console.log(_instanceof(arr, Array));
console.log(_instanceof(arr, fn2));
image.png
问题11:继承有什么作用?
继承是指获取类的属性,类的方法
作用有
1.子类通过继承了父类的属性和方法,就不需要重复代码了
2.子类可以重写和扩展父类的属性和方法,但是又不会影响父类
问题12: 下面两种写法有什么区别?
function People(name, sex){
this.name = name;
this.sex = sex;
this.printName = function(){
console.log(this.name);
}
}
var p1 = new People('饥人谷', 2)
//方法2
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.printName = function(){
console.log(this.name);
}
var p1 = new Person('若愚', 27);
第一种写法是:p1的内部有name,sex属性和printName方法,p1的 _ _ proto _ _ 指向People的prototype对象
第二种写法是p1的内部有name,sex属性,p1的 _ _ proto_ _指向People的prototype对象,printName方法存放在Person的prototype对象中
问题13: Object.create 有什么作用?兼容性如何?
object.create()创建一个新对象,并且该对象的原型指向Object.create()的第一个参数对象。
var f={a:1,b:3};
var s=Object.create(f);
console.log(s.__proto__==f);
image.png
兼容性:
凡实现ECS5标准的浏览器,都能使用,IE9以上
问题14: hasOwnProperty有什么作用? 如何使用?
hasOwnProperty是判断一个属性是否是对象自己所拥有的属性而不是原型对象中的。
var buz = {
fog: 'stack'
};
for (var name in buz) {
if (buz.hasOwnProperty(name)) {
alert("this is fog (" + name + ") for sure. Value: " + buz[name]);
}
else {
alert(name); // toString or something else
}
}
问题15:如下代码中call的作用是什么?
function Person(name, sex){
this.name = name;
this.sex = sex;
}
function Male(name, sex, age){
Person.call(this, name, sex); //这里的 call 有什么作用
this.age = age;
}
call作用是让Male继承Person的name,sex属性
问题16: 补全代码,实现继承
function Person(name, sex){
// todo ...
}
Person.prototype.getName = function(){
// todo ...
};
function Male(name, sex, age){
//todo ...
}
//todo ...
Male.prototype.getAge = function(){
//todo ...
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();
修改代码如下:
function Person(name, sex){
this.name=name;
this.sex=sex;
}
Person.prototype.printName = function(){
console.log(this.name);
};
function Male(name, sex, age){
Person.call(this,name,sex);
this.age=age;
}
//将Male的原型对象指向Person,使用create方法是创建一个新的对象,且新函数的原型对象与Person的原型对象相同。这样做的原因是为了防止
Male修改的时候影响父元素的原型对象。
Male.prototype=Object.create(Person.prototype);
Male.prototype.constructor=Male;
Male.prototype.getAge = function(){
console.log(this.age);
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();
image.png
总结:对于this的思考,this就是call函数传入的第一个参数。函数调用的时候引入call思考就会很任意的明白this的指向了。
网友评论