this 相关问题
1.apply、call 、bind有什么作用,什么区别
- fn.apply(context , paramArray) , 第一个参数context被设置为this , 其他参数使用数组的形势。
- fn.call(context , param1 , param2) , 第一个参数context被设置为this , 其他参数使用列表的形势。
- obj.fn.bind(obj) , 返回一个新函数,并将参数设置为函数的this
2.以下代码输出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()
这个代码可以转换成:
var john = {
firstName: "John",
sayHi: func
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi()
所以调用john对象的sayHi属性得到属性值func , 然后由于func是个函数,后面加了一个() , 变成执行func函数,得到结果为: john: hi!
3.下面代码输出什么,为什么
func()
function func() {
alert(this)
}
我们也可以写成这种形式:
func.call(undefined)
function func() {
alert(this)
}
所以它的this是window , 输出window
4.下面代码输出什么
document.addEventListener('click', function(e){
console.log(this); //document , 在事件中,this指向的是被监听的DOM源对象
setTimeout(function(){
console.log(this); //setTimeout和setInterval的this都是window
}, 200);
}, false);
5.下面代码输出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)
使用call的形式调用func,john被设置为func的this,输出this,firstName想当于输出john.firstName , 输出结果为John。
6.以下代码有什么问题,如何修改
var module= {
bind: function(){
var _this = this;
$btn.on('click', function(){
console.log(this) //this指$btn这个源DOM
_this.showMsg(); /*调用showMsg这个属性,需要使用它的对象module,所以应该将context设置为module,所以如果想使用this
的话,应该在module的作用域内将this赋予一个变量,然后调用这个变量就可以使用module作用域内的this*/
})
},
showMsg: function(){
console.log('饥人谷');
}
}
原型链相关问题
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();
Person函数声明的时候,创造一个prototype对象,此时这个对象是空的,后面给它添加了一个sayName方法,p是一个构造函数,通过new得来,在查找sayName时,在p的prototype里面找不到,于是顺着它的原型链往上找,p的proto指向Person的prototype中的方法sayName , 于是P就可以使用sayName的方法了。Person的prototype对象里面的constructor就是Person。
8.上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链。
可以调用,toString是由p的proto属性指向他更高级的类,得来的,p是一个函数,所以它的类可以是对象,所以p的proto找到了对象的prototype中的toString()方法,假设在对象的prototype当中没有找到toString,它还会往更高级的类上面去找,直到找到为止,如果最后还找不到,就返回一个undefined,这样一种依靠proto指向来寻找方法的这个过程,就像一条锁链,而由于是原型proto在这一过程当中去寻找,所以形象的称之为原型链。
9.对String做扩展,实现如下方式获取字符串中频率最高的字符
function String(str){
this.str = str;
}
String.prototype = {
constructor: String,
getMostOften: function () {
var strArr = this.str.split('');
var max = 0;
var sum = 0;
var letter = [];
var repeatLetter = false;
for(var i=0; i<strArr.length; i++){
for(var j=0; j<strArr.length; j++){
if(strArr[i] === strArr[j]){
sum++;
}
}
if(sum > max){
max = sum;
letter = [];
letter.push(strArr[i]);
}else if(sum === max){
for(var k=0; k<i; k++){
if(strArr[k] === strArr[i]){
repeatLetter = true;
}
}
if(!repeatLetter){
letter.push(strArr[i]);
}
}
sum = 0;
repeatLetter = false;
}
return letter.join(',');
}
};
var a = new String('11112222233333');
var b = a.getMostOften();
console.log(b);
10.instanceOf有什么作用?内部逻辑是如何实现的?
判断一个对象是不是某个类型的实例,如 [1,2,3] instanceOf Array
, 返回结果为boolean。
它的内部逻辑是通过原型链的继承机制来实现的,核心代码如下:
function instanceOf(obj,func) {
if(obj.__proto__ === func.prototype){
return true;
}else{
return false;
}
}
继承相关问题
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是添加属性,方法2是添加方法。方法1创建一个构造函数的时候,不管你是否使用printName它都会创造这个属性。而方法2的printName是根据你自己的需要来决定的,你不使用这个方法它就不会在创建构造函数的时候创建出来,方法2就起到了节省内存的作用。
13.Object.create 有什么作用?兼容性如何?
使用指定的原型对象及其属性去创建一个新的对象。示例代码如下:
function person(name, age) {
this.name = name;
this.age = age;
}
person.prototype = {
constructor: person,
sayName: function () {
console.log(this.name);
}
}
function people(sex, professional) {
this.sex = sex;
this.professional = professional;
}
people.prototype = {
constructor: people,
saySex: function () {
console.log(this.sex);
}
}
//现在我指定person的原型对象和属性为people.prototype
person.prototype = Object.create(people.prototype);
person.prototype.constructor = person;
console.log(person.prototype);
14. hasOwnProperty有什么作用? 如何使用?
判断某个属性是否是自身属性而不是继承得来的,如果是则返回true , 如果不是则返回false。
示例代码如下:
function person(name, age) {
this.name = name;
this.age = age;
}
person.prototype = {
constructor: person,
sayName: function () {
console.log(this.name);
}
}
if(person.hasOwnProperty('toString')){
console.log(1);
}
if(person.hasOwnProperty('name')){
console.log(2);
}
//输出结果为2
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将this变成Male , 而不是Person。从而使得Male可以继承Person的属性。
16.补全代码,实现继承
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.getName = function(){
console.log(this.name);
};
function Male(name, sex, age){
Person.call(this, name, sex);
this.age = age;
}
Male.prototype = Object.create(Person.prototype);
Male.prototype.constructor = Male;
Male.prototype.getAge = function(){
console.log(this.age)
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.getName();