构造函数
惯例:
构造函数始终应该以一个大写字母开头(借鉴自其他OO语言,因为JavaScript不是一个面向对象(oo)的语言,它只是基于对象(bo)。
构造函数本身也是函数,只不过可以创建对象而已。
构造函数和普通函数没有什么区别,只不过是用new来调用;使用new操作符会经历一下4步:
(1)创建一个新对象;
(2)将构造函数作用域赋给新对象(所以this就指向了这个新对象);
(3)执行构造函数中的代码(为这个新对象添加属性)
(4)返回新对象
1 | function People() { |
JS中没有类的概念,我们这里只是和Java、C++、C#做一个类比,JS中只有构造函数而没有类!当一个函数被new操作符调用的时候,它总能返回一类的具有相同属性群的对象,感觉在“构造东西”,所以我们称为构造函数。这个函数很神奇,像一个模子,在制作类似的对象。
判断函数是否为构造函数
是否被new操作符调用
1 | function Test(a,b){ |
如果构造函数里写了return情况
- 如果return这个基本类型值,则无视这个return,该return什么还是return什么,但是return阻止了构造函数的执行;
1 | function Test(a, b, c) { |
- 如果return了引用类型值,则返回你return的这个,原有return被覆盖。(new四步走就失效了)
1 | function Test(a, b, c) { |
原型链
1. prototype
每一个函数天生都有prototype属性,指向一个空对象。也就是说,我们不需要定义这个prototype属性,任何一个函数只要写出来,它就拥有了prototype属性。
当这个构造函数被new的时候,它的每一个实例的proto属性,也指向这个对象
1 | function Test(a,b,c) { |
我们称Test.prototype是Test构造函数的“原型”,Test.prototype是test的“原型对象”
2. __propto__
有原型链查找功能。当实例身上没有某个属性的时候,系统会沿着proto去寻找它的原型对象身上有没有这个属性。
1 | function Test(a, b, c) { |
3.方法的定义在原型上
我们刚才知道如果把函数写在构造函数里面,就相当于定义在了对象身上,此时函数会产生多个不同副本,影响程序效率。此时可以把函数定义在构造函数的原型上,这样所有new出的东西,proto就会指向这个对象,从而能够使用这个方法
1 | function People(name, age, sex) { |
4. hasOwnProperty()方法
可以检测一个属性是存在于实例中,还是存在于原型中。这个方法(不 要忘了它是从 Object 继承来的)只在给定属性存在于对象实例中时,才会返回 true。
1 | function Person() { |