一、this
- this的指向
- 严格模式下指向 undefined
- 普通函数指向 window
- 对象中的函数指向 对象本身
- 事件处理函数指向 事件源
- 箭头函数指向 指向父元素的指向
- 改变this的指向
- call() 用于改变this指向 第一次参数表示要改变成的那个this指向,后面的参数表示该函数的参数
fn() -> fn.call()
第一个参数表示要改变成的那个this指向,后面的参数表示该函数的参数
-
bind() 用于改变this指向,bind 只会改变this指向,但不会调用函数 -- 返回了这个函数
-
apply() 用改变this指向,apply 的第二个参数必须是一个数组(原函数的参数)
const obj1 = {
name : 'yy' ,
say : function () {
console.log(this.name);
}
}
const obj2 = {
name : 'cc' ,
say : function () {
console.log(this.name);
}
}
obj1.say() // yy
obj2.say() // cc
obj2.say.call(obj1) // y
function fn(n,m) {
console.log(n);
console.log(this);
}
fn(3)
fn.call(document , 4)
fn.bind(obj2 , 5)()
fn.apply(obj1 , [8 , 7])
二、面对对象的三大特性
- 封装,继承,多态
继承
- 构造函数的继承
- 可以调用父类的构造函数然后改变他的this指向
- 缺点:无法继承父类的原型对象的属性和方法
function Person(name , age) {
this.name = name ;
this.age = age ;
this.type = '人' ;
}
Person.prototype.say = function () {
console.log('我是人');
}
function YellowPerson(name , age) {
// 调用了一个函数,改变了它的this指向
Person.call(this , name , age) ;
this.color = 'yellow' ;
this.talk = function () {
console.log('我黄种人');
}
}
const y = new YellowPerson('cc' , 18) ;
console.log(y);
- 原型继承
- 实例化父类,把他放在子类的原型对象上
- 缺点:无法向父类传参
function Person(name , age) {
this.name = name ;
this.age = age ;
this.type = '人' ;
}
Person.prototype.say = function () {
console.log('我是人');
}
function YellowPerson(name , age) {
this.color = 'yellow' ;
this.talk = function () {
console.log('我黄种人');
}
}
YellowPerson.prototype = new Person('cc' , 18) ;
const y = new YellowPerson('yy' , 6) ;
console.log(y);
console.log(y.type);
y.say()
- 组合继承
- 构造函数继承 + 原型继承
- 缺点:原型链上出现了多余的属性
function Person(name , age) {
this.name = name ;
this.age = age ;
this.type = '人' ;
}
Person.prototype.say = function () {
console.log('我是人');
}
function YellowPerson(name , age) {
Person.call(this , name , age) ;
this.color = 'yellow' ;
this.talk = function () {
console.log('我黄种人');
}
}
YellowPerson.prototype = new Person('cc' , 18) ;
const y = new YellowPerson('yy' , 6) ;
console.log(y);
console.log(y.type);
y.say()
console.log(y.name);
- 原型对象的继承
- 原型对象的深复制。即把父类的原型对象进行深复制(遍历或者使用展开运算符)
function Person(name , age) {
this.name = name ;
this.age = age ;
this.type = '人' ;
}
Person.prototype.say = function () {
console.log('我是人');
}
function YellowPerson(name , age) {
Person.call(this , name , age)
this.color = 'yellow' ;
this.talk = function () {
console.log('我黄种人');
}
}
YellowPerson.prototype = {...Person.prototype} ;
YellowPerson.prototype.aa = 'a' ;
const y = new YellowPerson('yy' , 19) ;
console.log(y);
console.log(Person.prototype);
- 寄生式继承
- 中间件继承 -- 继承原型对象上的属性和方法
- 创建一个空的构造函数
function Fn(){}
- 让这个构造函数的原型对象指向父类的原型对象
Fn.prototype = fn2.protype
- 也就是说这个构造函数就有了父类的原型对象上的属性和方法
new Fn()
fn.prototype = new Fn()
- 虽然也是共享地址,fn2的改变会影响Fn,但fn的prototype改变不会影响到fn2
- ES6的继承
- extends 关键字 继承 子类继承父类
- super()函数
class 子类 extends 父类{
constructor(){
//super继承父类的属性和方法
//这个函数类似于person.call(this.name)
super(参数,参数)//向父类传参
}
}
class Person {
// 相当于构造函数
constructor(name , age) {
this.name = name ;
this.age = age ;
this.type = '人'
}
say() {
console.log('人');
}
}
// extends 继承
class YellowPerson extends Person {
constructor(name , age) {
// super 继承父类的属性和方法 ,
// 这个函数类似于 Person.call(this , name , age) + 原型对象的继承
super(name , age) ; // 向父类传参
this.color = 'yellow' ;
}
talk() {
console.log('我是黄种人');
}
}
const y = new YellowPerson('yy' , 20) ;
console.log(y);
三、链式操作
- 链式操作能够实现的本质是返回了同类型的数据,当返回值不再是同类型数据则链式中断
const arr = [1,2,3] ;
// 链式 数组的链式操作 返回值是数组
const res = arr.slice(0,2).concat(arr).push('a') ;
function fn() {
return function () {
console.log(666);
}
}
// 链式 函数的链式操作 返回 一个函数
fn()()
const str = 'hello' ;
// 链式 字符串的链式操作 返回值是字符串
const str2 = str.substring(0,3).concat('hi').includes('h') ;
- jq的链式操作
- 返回值为this一个对象,同数据类型就能链式