1.工厂模式、原型模式、构造函数模式、组合模式。优缺点
2.简述什么是原型
3.简述什么是原型链
4.简述this指向,如何改变this指向
5.new操作符具体干了什么
工厂函数
// 优点: 返回 新对象,互不影响
// 缺点: 代码重复(相同方法)、
// 没有从属(不能知道对象从那里来)–>instanceof 只能判断 是 对象,不能判断属于谁
原型模式
// 优点: 公共/相同 的 属性 、方法 不重复
// 有从属关系
// 缺点: 原型上的 属性不可单独改变
构造函数模式
//优点: 有从属
//缺点: 代码重复(相同方法)、
//共识:构造函数首字母大写
组合模式
// 组合模式 (构造 + 原型)
// 有从属关系
// 不重复
原型:每个函数中都有一个 prototype 属性 ,属性的值是对象,这个对象 叫原型对象
原型链
所有对象中 都有 一个 __proto__
,指向 对象 构造函数 的 原型(prototype),一直指向 null 为止。
原型是什么?
在JavaScript中原型是一个prototype对象,用于表示类型之间的关系。
原型链是什么?
JavaScript万物都是对象,对象和对象之间也有关系,并不是孤立存在的。对象之间的继承关系,在JavaScript中是通过prototype对象指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的链条,专业术语称之为原型链。
4.简述this指向,如何改变this指向
普通函数 指向 调用时所在对象 (谁调用指向谁)
全局函数 this 指向window
对象中 this 指向 当前对象
事件中 this 指向 发生事件的dom 对象
闭包this 指向 window
计时器 this 指向 window
// fn 函数里 的this 指向 obj 对象
// 第一个参数 this 指向的对象
fn.call(obj,1,2);
fn.apply(obj,[1,2]);
fn.bind(obj,1,2)();// 需要手动调用
fn.bind(obj)(1,2);// 需要手动调用
call()、apply()、bind() 区别
call、apply 自动调用
bind 手动调用()
call() 传参是 逗号隔开
apply() 传参 [] 包裹
bind() 传参逗号隔开 写在 前面 /后面的括号内
call() 方法 .call(obj,2,3)
apply() 方法 .apply(obj,[2,3])
call 传参是 逗号隔开,但是apply 传参是 数组
bind()方法 .bind(obj)(2,3)
5.new操作符具体干了什么
var obj={}; // 创建对象
Fn.call(obj,"gao",19); // 改变构造函数的this 指向 --指向 obj
obj.__proto__= Fn.prototype; // 将构造函数的 prototype(原型) 赋值 给对象的 __proto__(原型链)
// 返回 对象。
console.log(obj);
//1 创建一个空对象 var obj={}
//2 设置新对象的constructor属性为构造函数的名称,设置新对象的__proto__属性指向构造函数的prototype对象;
// obj.constructor = 'Car'
// obj.__proto__ = Car.prototype
//3.使用新对象调用函数,函数中的this被指向新实例对象:
// Car.call(obj)
//4.返回这个对象obj
function a(){
}
a.prototype // {"constructor":a函数本身,__proto__: Object.prototype}====>原型对象
// 公式
a.prototype.constructor == a// 函数 的 原型对象 的 构造函数 == 函数本身
//创建构造函数
function Gou(){
}
// 函数原型对象上绑定属性或方法
Gou.prototype.name="gao";
//new 操作符 将 构造函数 转为 实例对象
var obj= new Gou();
// 对象的 `__proto__` 指向构造函数的原型对象
obj.__proto__ == Gou.prototype;
Gou.prototype.__proto__ == Object.prototype
Object.prototype.__proto__ ==null