1、函数的定义:
声明式函数定义:function 函数名(){}
函数表达式:let fun = function(){}
new Function 形式: var fun1 = Function(arg1, arg2, arg3, ... argN,body); // body 要创建函数的函数体
Function 构造函数所有的参数都是字符串类型。
通过 new 函数名 来实例化对象的函数叫构造函数
构造函数的主要功能为初始化对象,特点是和 new 一起用
构造函数就是在为初始化的对象添加属性和方法
构造函数定义时首字母大写(规范)
2、任何对象都是由一个构造函数创建的
对象 → __proto__ → prototype
function Person(){...} // Person.prototype → Object{}
var p = new Person(); // p.prototype → undefined
⇒ 方法才有 prototype ,普通对象无 prototype。
任何对象都有构造函数,Person 这种方法的构造函数是 Function 。
p.constructor → function Person(){}
Person.constructor → function Function(){}
{}.constructor → function Object(){}
Object.constructor → function Function(){}
[].constructor → function Array(){}
注意: constructor 易被改变,一般不用,此处只是打印一下这些对象的构造函数是什么。
3、构造函数
function 声明的函数直接调用的话就是好一个普通函数,用函数 new 产生对象时,该函数才是 new 出来对象的构造函数。
声明 function 关键字的方法,会为该方法添加一个 prototype 属性,指向默认的原型对象,且此 prototype 的 constructor 属性也指向方法对象。
function Hello(){...}
Hello.prototype ⇒ Object{} → 内部的 constructor 指向 Hello 方法
Hello.prototype.constructor ⇒ function Hello(){...}
var h = new Hello();
h.constructor ⇒ function Hello(){...}
Object.getPrototypeOf(h) == Hello.prototype ⇒ true; // getPrototypeOf : 获取 __proto__
new 出来的对象,它的 constructor 指向了方法对象,它的 __proto__ 与 prototype 相等。
new 一个对象,其 __proto__ 指向了方法的 prototype ,且 constructor 指定了 prototype 的 constructor。
4、创建一个对象的过程:
function He(name){ this.name = name; }
var h = new He('小明');
// 伪代码
function newObj(name){
var obj = {};
obj.__proto__ = He.prototype;
obj.constructor = He.prototype.constructor;
var result = He.call(obj, name);
return typeof result === 'object' && result!=null ? result : obj; // 当无返回对象或默认时返回 obj
}
var hh = newObj('开心');
打印 hh、h,虽然 hh!=h,hh、h的结构一样。
过程:创建空对象 → 设置 __proto__ 指向方法原型 → 设置 constructor → 用新对象做 this指向方法 → 返回新对象
5、原型链
He
|→ name: '小明'
|→ __proto__ // 此对象时 He.prototype
|→ → constructor
|→ → __proto__ // 此对象时 Object.prototype, 再往上就没有 __proto__ 的指向了
原型链 → 依赖对象的 __proto__ 的指向,当自身不存在的属性时,就一层层的扒出创建对象的构造函数,直至 Object 时,就没有 __proto__ 指向了。
function Person(name){ this.name = name; }
var p = new Person();
// p → Person.prototype → Object.prototype → null
原型链继承:
function Person(name, age){ this.name = name; this.age = age; }
// 1、直接替换原型对象
var parent = {
sayHello: function(){ console.log(...); }
}
Person.prototype = parent;
var p = new Person('张三’, 50);
p.sayHello();
// 2、混入式原型链继承
function Student(name, age){ this.name = name; this.age = age; }
var parent2 = {
sayHello: function(){ console.log(...); }
}
for(var k in parent2){
Student.prototype[k] = parent2[k];
}
var p = new Student('张三', 50);
p.sayHello();