引例
构造函数:可以构造出对象的函数
假设我们要构建一个正方形,并求出它的周长和面积
function createSquare(widh){
let obj = Object.create(createSquare.squarePrototype)
obj.width = width
return obj
}
createSquare.squarePrototype = {
getArea(){
return this.width*this.width
},
getLength(){
return this.width*4
},
constructor:createSquare // 方便通过原型找到构造函数
}
let square = createSquare(5)
这段代码函数和原型紧密结合,还节省内存,可以说几乎完美,
JS之父希望将这种形式的代码直接固定在JS的基因之中,让开发者直接能够使用,
于是JS之父展现出了他对开发者的爱——new操作符
function Square(width){
this.width = width
}
Square.prototype.getArea = function(){
return this.width*this.width
}
Square.prototype.getLength = function(){
return this.width*4
}
let square = new Square(5)
可以看出,使用new来调用之后,代码变得更加简洁
(注:JS中,一个函数出生就默认带有prototype,prototype里默认有constructor,constructor的值就是函数自身)
所以,new X()做了些什么事呢?
- 自动创建空对象
- 自动为空对象关联原型,原型地址指定为 X.prototype
- 自动将空对象作为this关键字运行构造函数
- 自动return this
构造函数X
- X函数本身负责给对象本身添加属性
- X.prototype 对象负责保存对象的共有属性
如何确定一个对象的原型
为什么
- let obj = new Object() 的原型是 Object.prototype对应的对象
- let arr = new Array() 的原型是 Array.prototype对应的对象
- let square = new Square() 的原型是 Square.prototype对应的对象
因为是new操作故意这么做的
我们可以得出结论:
你是谁构造的,你的原型就是谁的prototype属性对应的对象
公式表示
对象.__proto__=== 其构造函数.prototype
例子
例1:
let x = {}
(注:new Object的缩写就是{})
请问:
- x 的原型是什么?
- x.__proto__的值是什么?
- 上面两个问题等价吗?
答案是等价的,它们的答案都是Object.prototype对应的对象
所以同理,
let square = new Square(5)
square的原型和square.__proto__的值都是Square.prototype对应的对象
例2:
- Object.prototype 是哪个函数构造出来的?
- 我们并不知道
- Object.prototype 的原型是什么?
- 没有原型
- Object.prototype.proto?
- null
类型与类
类型
- 类型是JS数据的分类,有7种
- 四基两空一对象
类
- 类是针对于对象的分类,有无数种
- Array,Function,Date,RegExp等都是常见的类
JS终极一问
-
window是谁构造的?
- Window
- 可以通过constructor属性看出构造者
-
window.Object是谁构造的?
- window.Function
- 所有函数都是window.Function构造的
-
window.Function是谁构造的?
- window.Function
- 因为所有函数都是window.Function构造的,这是「上帝」的安排
- 浏览器构造了Function,然后指定它构造者是自己
ES6引入新语法——class
class 也能够实现类似于new的操作
class Square{
constructor(width){
this.width = width
}
getArea(){
return this.width*this.width
}
getLength(){
return this.width*4
}
}
let square = new Square(5)
对于class,之后边学边补充