var
let
Promise
THIS 关键字理解
在浏览器中执行代码时,全局作用域里this和函数中的this 都指向window全局对象。
当函数被new关键字创建对象或被当做对象调用时 this 指向执行对象本身
console.log(this) //指向window
var firstName = "Peter",
lastName = "Ally";
function showFullName () {
//这个函数里的"this"会储存window对象的值
//因为与变量firstName和lastName一样,showFullName()函数是在全局作用域里定义的
console.log (this.firstName + " " + this.lastName);
}
/***
当函数被new关键字创建对象或被当做对象调用时 this 指向执行对象本身
***/
function fn() {
console.log(this) //fn
}
new fn()
var Dog = {
say() {
console.log(this) //Dog
}
}
Dog.say();
this最容易用错的情况
this
关键词在下列情况下最容易被用错:
- 当使用
this
的方法被“借用”时; - 当使用
this
的方法被用作回调函数时; - 当
this
被用于闭包-内部函数里时。
/**
* 当this 的方法被借用时,this 指向借用对象dog
*/
var person = {
name:'小明',
age:18,
say(){
console.log(this.name,this.age) //大黄 1
}
}
var dog = {
name:'大黄',
age:1
}
//采用apply 将say方法中的this 执行dog 对象
person.say.apply(dog)
/**
* 当this 的方法被用作回调函数时
* 当上下文环境改变时,在一个对象(persopn)里定义的方法(say)却到另外一个对象(dog)里执行(say)时,
* this关键词不再指代原对象person,而是指代调用该方法的对象(say()函数),
* 而say()函数本身的this 指向window全局
*/
var person = {
name: '小明',
age: 18,
say() {
console.log(this) //window
console.log(this.name, this.age) //undefined
}
}
var dog = {
name: '大黄',
age: 1,
say(event) {
event()
console.log(this.name, this.age) //大黄,1
}
}
dog.say(person.say)
//解决方案采用apply bind call 解决
dog.say(person.say.bind(person))
/**
* 当this被用于闭包-内部函数里时。
* 匿名函数里的this无法访问外部函数的this,所以在非严格模式下其被绑定了window对象上。
*/
var person = {
name:'小明',
age:18,
say(){
(function(){
console.log(this) //window
})()
}
}
person.say()
Call方法、Apply方法、Bind函数方法、箭头函数方法
call,apply,bind这三个方法其实都是继承自Function.prototype中的
主要作用:都是用来改变函数的this对象的指向的。
/**
* @augments apply(this,[args,args])
* @augments call(this,args,args)
* @augments bind(this,args,args)
*/
function jone(name,age,work){
this.name=name;
this.age=age;
this.work=work;
this.say=function(msg,err){
console.log(err)
console.log(msg+",我叫"+this.name+",我今年"+this.age+"岁,我是"+this.work)
}
}
var jack={
name:"jack",
age:'24',
work:"学生"
}
var pet=new jone();
pet.say.apply(jack,["欢迎您","test"])
pet.say.call(jack,"欢迎您","test")
pet.say.bind(jack,"欢迎您","test")()
/**
bind 官方提供的源码
**/
if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
// this instanceof fNOP === true时,说明返回的fBound被当做new的构造函数调用
return fToBind.apply(this instanceof fNOP
? this
: oThis,
// 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
aArgs.concat(Array.prototype.slice.call(arguments)));
};
// 维护原型关系
if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype;
}
// 下行的代码使fBound.prototype是fNOP的实例,因此
// 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例
fBound.prototype = new fNOP();
return fBound;
};
}
Javascript类的定义与继承
类的创建:
- 字面量静态对象;无需使用new 关键字就可直接使用
- function 构造函数; 使用new 关键字实例化对象
/**
* 字面量创建对象,静态对象无需实例化,直接使用
采用构造函数必须使用new 关键字实例化
*/
var persopn = {
name:"人类",
age:16
}
console.log(persopn.name)
/**
* 构造函数采用new关键字实例化对象
*/
var persopns = function(){
}
persopns.prototype = {
name:"外星人",
age:100
}
console.log(new persopns().name)
/**
* 原型链继承
*/
var persopn = function(){
this.name = "人类"
this.age = 18
this.say = function(){
console.log(this.name,this.age)
}
}
/**
* 构造函数采用new关键字实例化对象
*/
var persopns = function(){
this.name ="外星人"
}
persopns.prototype = new persopn()
Object
javascript 类型判断