1.为了节省内存,将对象的共同属性放在原型里
而new就是简化了上述逻辑
new X()自动做了四件事情(★★★)
- 自动创建空对象
- 自动为空对象关联原型,原型地址指定为X.prototype(即将 X.prototype 保存的地址复制到空对象.__proto__ 里)
- 自动将空对象作为this关键字运行构造函数
- 自动return this
构造函数X
X函数本身负责给对象本身添加属性
X.prototype对象负责保存对象的共用属性
代码规范
大小写
- 所有构造函数(专门用于创建对象的函数)首字母大写
- 所有被构造出来的对象,首字母小写
词性
new后面的函数,使用名词形式,如new Person()、new Object()
其他函数,一般使用动词开头,如createSquare(5)、createElement('dix')
你是谁构造的,你的原型就是谁的prototype属性对应的对象
原型公式
对象.__proto__==其构造函数.prototype
例子:
1
let x={}
请问:
1.x的原型是什么?
2.x.__proto___的值是什么?
答:问x的原型就相当于问x.__proto___的值是什么,x.__proto__===Object.prototype
2
let square = new Square(5)
请问:
1.square的原型是什么?
2.square.__proto__的值是什么?
答:问square的原型就相当于问square.__proto__的值是什么,square.__proto__===Square.prototype
3
请问:
1.Object.prototype是哪个函数构造出来的?
2.Object.prototype 的原型是什么?
3.Object.prototype.__proto__?
4(两种写法的对比)
prototype写法
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function(){ console.log('你好,我叫' + this.name) }
class写法(规则更多)
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHi() { return console.log('你好,我叫' + this.name) }
}
类型V.S.类
类型
类型是JS数据的分类,有7种,四基两空一对象
类
类是针对于对象的分类,有无数种
常见的有Array、Function、Date、RegExp等
数组对象
- 定义一个数组
let arr=[1,2,3]
let arr = new Array(1,2,3)元素为1,2,3
let arr = new Array(3)//长度为3
- 数组对象的自身属性
'0'/ '1'/ '2' / 'length'
注意,属性名没有数字,只有字符串
- 数组对象的共用属性
'push' / 'pop' / 'shift' / 'unshift' / 'join'
函数对象
- 定义一个函数
- function fn(x,y){return x+y}
- let fn2 = function fn(x,y){return x+y}
- let fn = (x,y)=> x+y
- let fn = new Function('x',y', 'return x+y')
- 函数对象自身属性
'name' / 'length'
- 函数对象共用属性
'call' /'apply' / 'bind'
JS终极一问
window是谁构造的?
Window
可以通过constructor属性看出构造者
window.Object是谁构造的
Window.Function
因为所有函数都是window.Function构造的
window.Function是谁构造的
Window.Function
因为所有函数都是window.Function构造的
浏览器构造了Function,然后指定它的构造者是自己
总结
- 「x 的原型」等价于「x.__proto__ 所指的对象」 ,有时为了方便,我们可以认为「x 的原型」等价于「x.__proto__ 」
- 一个对象的原型指的是这个对象与其他同类对象的公有属性的集合,比如 obj1 和 ob2 同时拥有 toString / valueOf,那么 toString / valueOf 等属性组成的对象,就是 obj1 和 obj2 的原型,这个原型的地址一般储存在构造函数的 prototype 里
- x.__proto__和 Object.prototype 存储着同一个对象的地址,这个对象就是 x 的原型
- 每个对象都有原型,但除了「根对象 Object.prototype」比较特殊,Object.prototype 这个对象的原型为空 null
- 所有函数一出生就有一个 prototype 属性(除了箭头函数)
- 所有 prototype 一出生就有一个 constructor 属性
- 所有 constructor 属性一出生就保存了对应的函数的地址
- 如果一个函数不是构造函数,它依然拥有 prototype 属性,只不过这个属性暂时没什么用
- 如果一个对象不是函数,那么这个对象一般来说没有 prototype 属性,但这个对象一般一定会有 __proto__ 属性
- 类型是对 JS 中数据的分类,类是对 JS 中对象的分类
- JS 中的类型有:数字、字符串、布尔、符号Symbol、null、undefined、对象(四基两空一对象)
- JS 中的类有:对象 Object、数组 Array、函数 Function 等
- Object.prototye 是「Object 构造出来的对象 obj」的原型,即 obj.__proto__ === Object.prototype
- Object.__proto__ 是 Object 的原型,由于 Object 是函数,而所有函数的原型都是 Function.prototype,所以 Object.__proto__ === Function.prototype
- Object.prototye 不是 Object 的原型,Object.__proto__ 才是 Object 的原型(还记着之前答过「x.原型 等价于 x.__proto__」吗,现在只不过是把 x 替换成 Object
- 所有「函数对象」的「构造函数」都是 Function
本文为$Iron的原创文章,著作权归本人和饥人谷所有,转载务必注明来源