构造函数
- 构造函数:可以构造出对象的函数。
- 构造函数负责给对象添加本身独有属性。
- 构造函数的prototype对象负责保存对象的共有属性。
- 代码规范
- 函数一般以动词、小写开头,例:
createSquare()、createElement()。
- 构造函数,会以名词、大写字母开头,例:
new Square()、new Cat()。
- 构造出来的对象,会以小写开头。
- 用Object()也是构造函数,但是它构造出来的对象是最没有特点的。
利用函数和原型构造对象
- 利用原型链的机制,来构造多个有共同特征的对象,可以避免代码的重复、占用内存过多。
let squareList = []
let widthList = [5, 6, 5, 6, 5, 6, 5, 6, 5]
function createSquare(width) {
let obj = Object.create(createSquare.squarePrototype)
obj.width
return obj
}
createSquare.squarePrototype = {
getArea() {
return this.width * this.width
},
getLength() {
return this.width*4
},
constructor: createSquare
}
for(let i = 0; i < widthList.length; i++) {
squareList[i] = createSquare(widthList[i])
}
console.log(squareList[0].getArea === squareList[1].getArea)
- 将上述代码用new优化,来简化成下面的代码:
let squareList = []
let widthList = [5, 6, 5, 6, 5, 6, 5, 6, 5]
function Square(width) {
this.width = width
}
Square.prototype.getArea = function(){
return this.width * this.width
}
Square.prototype.getLength = function() {
return this.width*4
}
for(let i = 0; i < widthList.length; i++) {
squareList[i] = new Square(widthList[i])
}
console.log(squareList[0].getArea === squareList[1].getArea)
- new在这段代码中,代替了
let obj = Object.create(createSquare.squarePrototype)的作用。
- new的作用
- 自动创建空对象。
let obj = Object.create()
- 自动创造并关联对象原型。
createSquare.squarePrototype
- 自动将空对象作为this关键字运行构造函数。
- 自动
return this。
- 注意
- 在这种构造方法中,只有
prototype.的属性才是共有属性。
- 要先创建原型,才能调用构造函数,因此
prototype.不能写在构造函数内容。
数组对象
- 定义一个数组:
var arr = [1, 2, 3]
var arr = new Array(1, 2, 3)
var arr = new Array(3)
- 数组对象的独有属性
- 数组对象的共有属性
- push():在数组末尾添加元素,并返回该数组的新长度。
- pop():在数组末尾删除一个元素,并返回该元素的值。
- shift():在数组开头添加元素,并返回该数组的新长度。
- unshift():在数组开头删除一个元素,并返回该元素的值。
- join():将一个数组的所有元素拼接成一个字符串,并返回这个字符串。
- 数组对象相比Object对象,就多一层原型。
let a = []
a.__proto__.__proto__ === window.Object.prototype
- 注意
函数对象
- 定义一个函数:
function fn(x, y){return x + y}
var fn2 = function fn(x, y){return x + y}
var fn = (x, y) => x + y
var fn = new Function('x','y','return x+y')
- 函数对象的独有属性
- 函数对象的共有属性
constructor属性
window是谁构造的?
- 通过constructor属性可以查看对象的构造者:
window.constructor
- 因此,window和Window不是一回事。后者其实应该是Window()。
window.Object是谁构造的?
window.Object.constructor
- 所有的函数都是Function()构造的。
- Window()也是Function()构造的。
Function()是谁构造的?
Function().constructor
- 浏览器构造了Function(),然后指定它的构造者为自己。
Object.prototype是谁构造的?
Object.prototype.constructor
- 浏览器构造了Object.prototype,然后指定它的构造者为Object()。
class语法
class语法进入的概念
class Square{
static x = 1
width = 0
constructor(width){
this.width = width
}
getArea(){
return this.width * this.width
}
getLength(){
return this.width * 4
}
get area2(){
return this.width * this.width
}
}
static x = 1:设置一个只能通过Square.x调用的静态变量x(类似Java)。
width = 0:为width设定初始值(默认值)。
get area2() {}:设置只读属性。调用只读属性时不用加小括号。
class中两种函数写法的区别
拓展
函数的prototype属性
- 所有JS中的函数,一开始就自带一个prototype属性。
JS中怎么知道函数有几个参数?
- 看文档
- 看源代码
JS中变量所存储的内容
- JS中变量只能存储简单数据类型或者地址。
- 因此prototype属性中存储的是原型的地址。
- Object() ≠ Object类型的原型
- JS源代码中不存在这样一个变量名
- 它的变量名为Object。
- 它所指向的地址有且仅拥有Object数据类型对象的所有属性。
- prototype属性不等于原型。
原型公式
对象.__proto__ === 其构造函数.prototype
- 任何对象都有以上规律。
Object.prototype是例外,因为它的值为null。
this和箭头函数
类型和类的区别
- 类型:JS数据的分类,共有七种。
- 类:针对与对象的分类,有无数种。