- 在函数被直接调用时this绑定到全局对象。在浏览器中,window 就是该全局对象,函数调用模式this指向window的全局对象
- setTimeout、setInterval这两个方法执行的函数this也是全局对象
- 构造函数调用:
构造函数调用模式this指向被构造的对象
new 运算符接受一个函数 F 及其参数:new F(arguments...)
。这一过程分为三步:
- 创建类的实例。这步是把一个空的对象的
__proto__
属性设置为F.prototype
- 初始化实例。函数 F 被传入参数并调用,关键字 this 被设定为该实例。
- 返回实例
- 方法调用模式 : this指向调用者
fn()
- 在事件处理程序中this代表事件源DOM对象
小陷阱:
var fn2 = obj1.fn;
fn2(); //this指向window
This相关问题
apply、call 、bind有什么作用,什么区别
-
Function.prototype.bind
- bind,返回一个新函数,并且使函数内部的this为传入的第一个参数,可以修改this作用域
因为函数原型尚有一个bind方法
所以任何函数__proto__上都有bind,都可以使用
-
call和apply设置this
-
call apply
,调用一个函数,传入函数执行上下文及参数
-
// 第一个参数都是希望设置的this对象
fn.call(context, param1, param2...) // call方法接收参数列表
fn.apply(context, paramArray) // apply接收参数数组
以下代码输出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi() // John:hi 因为this指向全局作用域
下面代码输出什么,为什么
func()
function func() {
alert(this) // window 函数调用模式this指向window的全局对象
}
下面代码输出什么
document.addEventListener('click', function(e){
console.log(this); // document 事件处理程序中this代表事件源DOM对象
setTimeout(function(){
console.log(this); // window setTimeout setInterval指向是全局对象
}, 200);
}, false);
下面代码输出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func() // undefined
func.call(john) //john .call第一个参数是希望设置的this对象指向join join.firstName
以下代码有什么问题,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么 指向$btn
this.showMsg();
}).bind(this) //修改加上 .bind(this)改变this的指向showMsg
},
showMsg: function(){
console.log('饥人谷');
}
}
原型链相关问题
- 实例化对象原型(
__proto__
)指向构造函数的prototype属性
arr.__proto__ === Array.prototype
有如下代码,解释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("Hello")
p.sayName();
- p实例化对象原型(
__proto__
)指向Person的prototype
属性 Person.prototype.constryctor === Person //true
-
p.constructor === Person // true
上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链。
toString()是从p原型上的原型上来的
- 任何类的
prototype
属性本质上都是个类Object的实例,所以prototype也和其它实例一样也有个__proto__
内部属性,指向其类型Object的prototype
对String做扩展,实现如下方式获取字符串中频率最高的字符
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次
String.prototype.getMostOften = function() {
var Str = {}; //空对象
var key ; //属性
for(var i = 0; i < this.length; i++){
key = this[i]; //key = 属性值
if(!Str[key]){
Str[key] = 1;
}
else{ //相同的+1
Str[key] ++;
}
}
var max = 0;
var strKey;
for(var k in Str){
if(Str[k] > max){
max = Str[k];
strKey = k;
}
}
return strKey;
}
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次
instanceOf有什么作用?内部逻辑是如何实现的?
-
作用:
instanceof操作符
,判断一个对象是不是某个类型的实例 -
逻辑实现: 判断一个东西是不是它的实例,首先看一个实例化对象原型(
__proto__
)是否等于函数的prototype,一直找下去
示例:
[1, 2, 3] instanceof Array; //true
[1,2,3].__proto__ === Array.prototype
[1,2,3].__proto__.__proto__ === Array.prototype
...
继承相关问题
继承有什么作用?
继承是指一个对象直接使用另一对象的属性和方法。
- 子类拥有父类的属性和方法,不需要重复写代码,修改时也只需修改一份代码
- 可以重写和扩展父类的属性和代码,又不影响父类本身
下面两种写法有什么区别?
//方法1
function People(name, sex){
this.name = name;
this.sex = sex;
this.printName = function(){
console.log(this.name);
}
}
var p1 = new People('meng', 2)
//方法2
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.printName = function(){
console.log(this.name);
}
var p1 = new Person('yym', 23);
方法2 将代码的属性和方法分开写,方法写在了原型链上,起到了公共代码的作用,有利于其他对象使用该对象的属性个方法
Object.create有什么作用?兼容性如何?
作用:
Object.create(proto)
创建一个拥有指定原型和若干个指定属性的对象
proto:一个对象,作为新创建对象的原型。或者为null。
hasOwnProperty有什么作用? 如何使用?
hasOwnProperty是Object.prototype的一个方法
判断一个对象是否包含自定义属性和方法,而不是原型链上的属性和方法
m.hasOwnProperty('name');
m.hasOwnProperty('printName');
Male.prototype.hasOwnProperty('printAge');
如下代码中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;
}
// 调用Person方法,指定Person方法中的this为Male,并传入参数sex,age
补全代码,实现继承
function Person(name, sex){
// todo ...
this.name = name;
this.sex = sex;
}
Person.prototype.getName = function(){
// todo ...
console.log('name: ' + this.name);
};
function Male(name, sex, age){
//todo ...
Person.call(this, name, sex);
this.age = age;
}
//todo ...
Male.prototype = Object.create(Person.prototype);
Male.prototype.constructor = Male;
Male.prototype.getAge = function(){
//todo ...
console.log( 'age: ' + this.age);
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();