构造函数
function Foo (name, age) { // 构造函数命名:大写字母开头
this.name = name
this.age = age
this.class = 'class-1'
// return this // 默认有这一行
}
var f = new Foo('David', 18)
构造函数-扩展
-
var a = {}其实是var a = new Object()的语法糖 -
var a = []其实是var a = new Array()的语法糖 -
function Foo(){...}其实是var Foo = new Function(…)的语法糖 - 使用
instance判断一个函数是否是一个变量的构造函数,如Date instanceof Object,会返回true
原型规则
- 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(
null除外) - 所有的引用类型(数组、对象、函数),都具有一个
__proto__属性(隐式原型),它是一个普通的对象 - 所有的函数,都有一个
prototype属性(显式原型),它也是一个普通对象 - 所有的引用类型(数组、对象、函数),
__proto__属性值指向它的构造函数的prototype属性值 - 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的
__proto__(即它的构造函数的prototype)中寻找
// 循环对象自身的属性
function f (){...}
var item
for (item in f) {
// 高级浏览器已经在for in 中屏蔽了来自原型的属性
// 但还是建议加上这个判断,为了程序的健壮性
if (f.hasOwnProperty(item)) {
console.log(item)
}
}
原型链
// 构造函数
function Foo(name, age) {
this.name = name
}
Foo.prototype.alertName = function () {
alert(this.name)
}
// 创建示例
var f = new Foo('David')
f.printName = function () {
console.log(this.name)
}
// 测试
f.printName()
f.alertName()
f.toString() // 要去 f.__proto__.__proto__ 中查找
Function与Object的关系
- 首先,js中,一切引用类型都是对象,包括函数、数组、对象。
- 一切对象都有一个根源,它是
Object.prototype,称之为“根源对象”。 - 根源对象之上没有其他根源,即
Object.prototype.__proto__ === null为true,js中除了字面量以外的一切引用对象都来自这个根源对象。 -
Function.__proto__ === Function.prototype为true。实际上,Function.prototype是一个内置函数,一切函数都派生自这个内置函数,它是一个内置函数工厂,这个内置函数对象的prototype指向“根源对象”。
Function和Object,既是函数,因为都可以通过Function()和Object()的方式执行;
又是对象,因为可以扩展属性,如Function.a = 1,Object.b = 2这样。
说他们是函数,因为他们都是通过上面第4条说的“内置函数工厂”,派生出来的,因此具备函数的特性。
说他们是对象,因为他们都是通过第2条说的“根源对象”,派生出来的,因此具备对象的特性。
下面是我做的一张图,有不合理或不正确的地方欢迎指正