new 操作符
案例对比
总结
new X() 自动做了四件事情
-
自动创建空对象
-
自动为空对象关联原型,原型地址指定为 X.prototype
-
自动将空对象作为 this 关键字运行构造函数
-
自动 return this
构造函数 X
-
X 函数本身负责给对象本身添加属性
-
X.prototype 对象负责保存对象的共用属性
代码规范
大小写
-
所有构造函数(专门用于创建对象的函数)首字母大写
-
所有被构造出来的对象,首字母小写
词性
-
new 后面的函数,使用名词形式
-
如 new Person()、new Object()
-
其他函数,一般使用动词开头
-
如 createSquare(5)、createElement('div')
确定一个对象的原型
-
let obj = new Object() 的原型是 Object.prototype
-
let arr = new Array() 的原型是 Array.prototype
-
let square = new Square() 的原型是 Square.prototype
-
let fn = new Function() 的原型是 Function.prototype
结论
- 你是谁构造的 · 你的原型就是谁的 prototype 属性 · 对应的对象
原型公式
- 对象._ _ proto _ _ === 其构造函数.prototype
类型&类
类型
-
类型是 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'
-
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'
问:
window 是谁构造的
-
Window
-
可以通过 constructor 属性看出构造者
window.Object 是谁构造的
-
window.Function
-
因为所有函数都是 window.Function 构造的
window.Function 是谁构造的
-
window.Function
-
因为所有函数都是 window.Function 构造的
-
浏览器构造了 Function,然后指定它的构造者是自己
知识点
-
JS 构造对象目前有两种方式,一种是用构造函数+prototype,一种是用 class。
-
关于「原型」,正确的是(多选)下文中的 x 均代表普通对象。
-
「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 属性(除了箭头函数)
-
所有 prototype 一出生就有一个 constructor 属性
-
如果一个函数不是构造函数,它依然拥有 prototype 属性,只不过这个属性暂时没什么用
-
如果一个对象不是函数,那么这个对象一般来说没有 prototype 属性,但这个对象一般一定会有 proto 属性
- 关于 Object.prototype,正确的是
-
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。很多人都搞不清楚 Object.proto 和 Object.prototype 哪一个才是 Object 的原型,其实只要记住公式就好办了)
分别用function和class写一个 Person 构造函数
function
function Person(name, age){
this.name = name
this.age = age
}
Person.prototype.sayHi = function(){
console.log(`你好,我是${this.name}`)
或者
console.log('你好,我是'+this.name)
}
class
class Person{
constructor(name, age){
this.name = name
this.age = age
}
sayHi(){
console.log(`你好,我是${this.name}`)
或者
console.log('你好,我是'+this.name)
}
}