JS对象分类

构造函数

1
2
3
4
5
6
7
8
9
10
11
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操作调用构造函数,创建一个对象

构造函数Square

  • Square函数本身负责给对象本身增加自身属性
  • Square.prototype负责创建对象的共有属性

new Square 自动帮你做了四件事

  1. 自动创建了一个空对象
  2. 自动为这个空对象关联原型,原型地址为Square.prototype
  3. 自动将空对象作为 this关键字 运行构造函数
  4. 自动 return this

规范

  • 构造函数,首字母大写
  • 被构造出来的对象,首字母小写
  • new 后面的函数,使用名词形式 eg: new Person()、new Circle()

练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.getArea = function() {
return Math.pow(this.radius, 2) * Math.PI;
}
Circle.prototype.getLength = function() {
return this.radius * 2 * Math.PI;
}

let circle = new Circle(5);
circle.radius
circle.getArea();
circle.getLength();

原型公式(JS里唯一的一个公式)

规律

  • 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中的类

类型 VS 类

  • 类型是JS数据的分类,包含7种数据类型(string、number、bool、symbol、undefined、null、object)
  • 类是针对对象的分类,常见的有(Array、Function、Date)

    为什么对象需要分类

  • 有很多对象拥有一样的属性和行为(函数),需要把他们归为一类,如 square1 和 square2,这样创建类似对象的时候就很方便
  • 还有很多对象拥有其他的属性和行为,所以就需要不同的分类。比如 Square / Circle / Rect 就是不同的分类,Array / Function 也是不同的分类

数组对象

  • 定义一个数组

    1
    2
    3
    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’ ‘join’ ‘shift’ ‘unshift’

函数对象

  • 定义一个函数

    1
    2
    3
    4
    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’

ES6 class新语法

用class重写circle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Circle {
constructor(radius){
this.radius = radius
}
getArea(){
return Math.pow(this.radius,2) * Math.PI
}
getLength(){
return this.radius * 2 * Math.PI
}
}
let circle = new Circle(5)
circle.radius
circle.getArea
circle.getLength

JS终极一问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1. window 是谁构造的

Window
可通过 constructor属性 查看构造者
window.__proto__ === Window.prototype

2.window.Object 是谁构造的

window.Function
因为所有函数都是由 window.Function 构造出来的
window.Object.constructor === window.Function

3. window.Function 是谁构造的

window.Function
因为所有函数都是由window.function构造的
自己构造自己?
浏览器构造了Function,然后指定它的构造者是自己

问答

  1. 关于 「原型」 ,正确的是
  • 「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
  1. 关于 prototype 属性,正确的有
  • 所有函数一出生就有一个 prototype 属性(除了箭头函数)
  • 所有 prototype 一出生就有一个 constructor 属性
  • 所有 constructor 属性一出生就保存了对应的函数的地址
  • 如果一个函数不是构造函数,它依然拥有 prototype 属性,只不过这个属性暂时没什么用
  • 如果一个对象不是函数,那么这个对象一般来说没有 prototype 属性,但这个对象一般一定会有 proto 属性
0%