原型和原型链
1 | |

1 | |


“函数即对象”
函数是第一类对象
- 在JavaScript中,对象所拥有的功能,函数一样拥有。
- 函数也是对象,唯一不同的地方在于,函数是可以调用的(invokable),也就是说函数会被调用以便执行某项动作。
- 函数式编程更易测试、扩展和模块化。
① 当任意一个普通函数用于创建一类对象时,它就被称作构造函数,或构造器。
1 | |

② 可以通过对象.constructor拿到创建该实例对象的构造函数。
1 | |
③ Function函数和Object函数是JS内置对象,也叫内部类,JS自己封装好的类.
④ 原型对象即实例对象自己构造函数内的prototype对象。
理解”函数即对象”
1 | |
Person虽被声明为一个函数,但它同样可以通过Person.constructor输出内容。输出内容说明Function函数是Person函数[普通声明的函数]的构造函数。
Function函数同时是自己的构造函数。
Function函数同样是Object这类内置对象的构造函数。
上面的声明函数的代码其实几乎等同于下面代码:
1 | |
在JS里,函数就是Function函数的实例对象。
总结:对象由函数创建,函数都是Function对象实例。
构造函数
constructor 返回创建实例对象时构造函数的引用。此属性的值是对函数本身的引用,而不是一个包含函数名称的字符串。
1 | |
构造函数本身就是一个函数,与普通函数没有任何区别,不过为了规范一般将其首字母大写。构造函数和普通函数的区别在于,使用 new 生成实例的函数就是构造函数,直接调用的就是普通函数。
普通函数创建的实例也有 constructor 属性
1 | |
Symbol是构造函数吗?
The
Symbol()function returns a value of type symbol, has static properties that expose several members of built-in objects, has static methods that expose the global symbol registry, and resembles a built-in object class but is incomplete as a constructor because it does not support the syntax “new Symbol()“.Symbol()函数返回类型为Symbol的值,具有公开内置对象的几个成员的静态财产,具有公开全局符号注册表的静态方法,类似于内置对象类,但作为构造函数是不完整的,因为它不支持语法“new Symbol”。
Symbol 是基本数据类型,但作为构造函数来说它并不完整,因为它不支持语法 new Symbol(),Chrome 认为其不是构造函数,如果要生成实例直接使用 Symbol() 即可。
1 | |
这里的 constructor 属性来自哪里?其实是 Symbol 原型上的,即 Symbol.prototype.constructor 返回创建实例原型的函数, 默认为 Symbol 函数。
constructor 值只读吗
对于引用类型来说 constructor 属性值是可以修改的,但是对于基本类型来说是只读的。
1 | |

原型
每个对象拥有一个原型对象,对象以其原型为模板,从原型继承方法和属性,这些属性和方法定义在对象的构造器函数的 prototype 属性上,而非对象实例本身。

fun 对象有一个原型对象 fun.prototype,其上有两个属性,分别是 constructor 和 __proto__,其中 __proto__ 已被弃用。

待整理
Symbol 作为构造函数来说并不完整,因为不支持语法 new Symbol(),但其原型上拥有 constructor 属性,即 Symbol.prototype.constructor。
引用类型 constructor 属性值是可以修改的,但是对于基本类型来说是只读的,当然 null 和 undefined 没有 constructor 属性。
__proto__ 是每个实例上都有的属性,prototype 是构造函数的属性,这两个并不一样,但 p.__proto__ 和 Parent.prototype 指向同一个对象。
__proto__ 属性在 ES6 时被标准化,但因为性能问题并不推荐使用,推荐使用 Object.getPrototypeOf()。
每个对象拥有一个原型对象,通过 __proto__ 指针指向上一个原型 ,并从中继承方法和属性,同时原型对象也可能拥有原型,这样一层一层,最终指向 null,这就是原型链。