Open yym-yumeng123 opened 7 years ago
在函数被直接调用时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对象
构造函数调用模式this指向被构造的对象
new F(arguments...)
__proto__
F.prototype
fn()
小陷阱: var fn2 = obj1.fn; fn2(); //this指向window
Function.prototype.bind
因为函数原型尚有一个bind方法 所以任何函数__proto__上都有bind,都可以使用
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` ![原型链图](http://upload-images.jianshu.io/upload_images/5983146-468972b2e3b0c7b5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ### 上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链。 - `toString()是从p原型上的原型上来的` - 任何类的`prototype`属性本质上都是个类Object的实例,所以prototype也和其它实例一样也有个`__proto__`内部属性,指向其类型`Object的prototype` ![原型链](http://upload-images.jianshu.io/upload_images/5983146-375290ffa6c372bb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![原型图](http://upload-images.jianshu.io/upload_images/5983146-fa3a226f2dd7d250.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ### 对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; }
### instanceOf有什么作用?内部逻辑是如何实现的? - **作用:**`instanceof操作符`,判断一个对象是不是某个类型的实例 - **逻辑实现:** 判断一个东西是不是它的实例,首先看一个实例化对象原型(`__proto__`)是否等于函数的prototype,一直找下去
示例: [1, 2, 3] instanceof Array; //true
[1,2,3].proto === Array.prototype [1,2,3].proto.proto === Array.prototype ...
## 继承相关问题 ### 继承有什么作用? > 继承是指一个对象直接使用另一对象的属性和方法。 1. 子类拥有父类的属性和方法,不需要重复写代码,修改时也只需修改一份代码 2. 可以重写和扩展父类的属性和代码,又不影响父类本身 ### 下面两种写法有什么区别?
//方法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。 ![兼容性](http://upload-images.jianshu.io/upload_images/5983146-69695dd7a100e81c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ### 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();
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);
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('饥人谷'); } }
arr.proto === Array.prototype
function Person(name){ this.name = name; } Person.prototype.sayName = function(){ console.log('My name is :' + this.name); } var p = new Person("Hello") p.sayName();
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次
示例: [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);
hasOwnProperty是Object.prototype的一个方法 判断一个对象是否包含自定义属性和方法,而不是原型链上的属性和方法
m.hasOwnProperty('name'); m.hasOwnProperty('printName'); Male.prototype.hasOwnProperty('printAge');
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();