this 相关问题
问题1: apply、call 、bind有什么作用,什么区别
作用: 给函数指定this。是用来指定上下文的
区别: bind:bind()会创建一个新的函数,将其中的值,作为原来函数的this。例如xx.bind(obj)中,obj为xx的this 。将函数体中的this绑定到对象上,然后返回一个新的函数。
call: call()是使用一个指定的this值和相关参数的前提下调用函数或方法。接受的参数为若干个参数的列表。简单来说,就是可以指定函数内部this的指向(即在此函数执行时所在的作用域),让在所指定的作用域中,调用该函数。就是var obj={};function fn(){ return this;};fn.call(obj),call改变this的指向。让fn的this是指向obj的,在obj的作用域中运行
apply: apply()效果同call(),不过其接受的参数为数组。
问题2: 以下代码输出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi() ==》方法调用
输出:
john hi!
问题3: 下面代码输出什么,为什么
func()
function func() {
alert(this)
} ==》函数调用
输出: window,因为在function中的this,没有找到对象,所以继续向外找,
而function的外部环境为window,则输出window
问题4:下面代码输出什么
document.addEventListener('click', function(e){
console.log(this);
setTimeout(function(){
console.log(this);
}, 200);
}, false);
输出:document
window
问题5:下面代码输出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)
输出:john
原因:call()函数为func函数绑定了this=john
call()函数将func函数的this指向了john,并且func的执行在john的作用域中
问题6: 以下代码有什么问题,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么
this.showMsg();
})
},
showMsg: function(){
console.log('饥人谷');
}
}
问题:console.log出来的是$btn 饥人谷 ;//不知道。
当调用module.bind()的时候。this.showMsg()无法调用。因为这里的this指向了$btn。所以将this.showMsg()改为module.showMsg();
或是通过嫁接方式;var that=this;that.showMsg();
原型链相关问题
问题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();
关联:p是Person的构造对象,而Person是构造函数。 在new的过程中,p的-proto-指向 Person,因为Person的原型上绑定一个方法:sayName,即constructor下有sayName。所以p 拥有属性:name;和方法sayName()。
问题8: 上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链。
来自上一级的原型。
https://www.draw.io/#Hkomolei%2Ftry%2Fmaster%2FUntitled%20Diagram.xml
原型链:所有的对象都有-proto-这个属性,这个链接到另一个-proto-,像这样一个个-proto-相链接起来的样子,称为原型链。对于函数,则是prototype了。
问题9:对String做扩展,实现如下方式获取字符串中频率最高的字符
var str = 'ahbbccdeddddfg';
String.prototype.getMostOften =
function () {
// var str = 'ahbbccdeddddfg';
var str=this;
// console.log(this);
var o = {};
for (var i = 0; i < str.length; i++) {
var char = str.charAt(i);
if (o[char]) {
o[char]++; //次数加1
} else {
o[char] = 1; //若第一次出现,次数记为1
}
}
// console.log(o); //输出的是完整的对象,记录着每一个字符及其出现的次数
//遍历对象,找到出现次数最多的字符的次数
var max = 0;
for (var key in o) {
if (max < o[key]) {
max = o[key]; //max始终储存次数最大的那个
}
}
for (var key in o) {
if (o[key] == max) {
//console.log(key);
// console.log("最多的字符是" + key);
// console.log("出现的次数是" + max);
return key;
}
}
}
var ch = str.getMostOften();
console.log(ch);
问题10: instanceOf有什么作用?内部逻辑是如何实现的?
作用: instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
就是检测一个原型链上是否存在某个prototype。a.instanceof b.prototype :就是a的原型链中是否存在b.prototype;
实现逻辑:让其一层一层沿着原型链去查找,找到就return true;
继承相关问题
问题11:继承有什么作用?
继承:一个对象继承另一个对象的所有的属性和方法。可以得到另一个对象的属性和方法。
问题12: 下面两种写法有什么区别?
//方法1
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);
区别:方法1是 绑定在People上。方法2的printName是绑定到原型上。在new多个实例的时候,方法2可以直接调用。在多次调用的时候可以优化内存空间。而方法1要多次写入。
同时方法2中要更改prototype的时候,其的每一个实例的printName都会改变。而方法1需要每个都是修改。
问题13: Object.create 有什么作用?兼容性如何?
Object.create() 方法使用指定的原型对象和其属性创建了一个新的对象。简单来说就是可以手动的去指定对象的原型。创建一个新的对象,第一层的原型链指向对应的参数。
兼容性:支持各个浏览器。ie需要ie9以上。
问题14: hasOwnProperty有什么作用? 如何使用?
作用:看对象上的属性是属于自己的,还是从原型链继承来的。
使用:object.hasOwnPrototype(" 属性")
问题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;
}
作用:让Male继承Person中的属性。手动将this指向Person。就是将Person中的this引用到Male中。
问题16: 补全代码,实现继承
function Person(name, sex){
// todo ...
this.name=name;
this.sex=sex;
}
Person.prototype.getName = function(){
// todo ...
console.log(this.name);
};
function Male(name, sex, age){
//todo ...
Person.call(this,name,sex)
this.age=age;
//this.printName=function(){
// console.log(this.name)
//}
this.printName=Person.prototype.getName;
}
//todo ...
Male.prototype.getAge = function(){
//todo ...
console.log(this.age)
};
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;
//this.printName=function(){
// console.log(this.name)
//}
//this.printName=Person.prototype.getName;
}
//todo ...
Male.prototype=new Person() ; //继承:将一个对象的prototype指向要继承的对象即可
Male.prototype.getAge = function(){
// todo ...
console.log(this.age)
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();