1.一般写法规范
构造函数都应该以 一个大写字母开头,eg:
function Person(){…}
而非构造函数则应该以一个小写字母开头,eg:
function person(){…}
2.调用方式
任何函数,只要通过 new 操作符来调用,那它就可以作为构造函数 ;
任何函数,如果不通过 new 操作符来调用,那它跟普通函数也没有什么两样。
//创建函数
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
console.log(this.name);
}
}
//当做构造函数使用
var person = new Person('Nicholas',29,'Software Engineer');
//过程:在new关键字声明后,则会创建了一个对象,并且Person内部的this指向着这个对象,同时继续执行Person函数内部代码,全部执行完后,则返回this所指向的对象
person.sayName();//'Nicholas'
//当做普通函数调用
Person('Greg',27,'Doctor');//返回值为undefined
//过程:因为函数外部没有对象调用,所以函数内部this指向全局对象window,继续执行Person函数
//又因为有this.name = name;等代码,所以相当于执行了window.name = name
window.sayName();//'Greg'
函数如果有返回值的情况则分为引用类型和值类型两种情况:
//函数显式写了返回值为引用类型时,
//1.当使用new之后,函数(包括构造函数)返回值为该引用类型
//2.当普通函数调用时,返回显式的return值
function test()
{
this.a=10;
return function() {
return 1;
}
}
var m=new test(); // 内部this指向以test为构造函数的对象,但后面没有返回引用,所以会被丢弃
var n=test(); // 内部this指向window全局对象,其中 window.a = 10
console.log(m);//返回return后面的闭包
console.log(n);//返回return 后面的闭包
运行结果m的值和n的值是一样的,都是test函数返回的闭包,而this引用的对象和this.a=10的赋值结果全部被丢弃。
如果一个函数的返回值是一个值类型,那么这个函数作为构造函数用new运算符执行构造时,它的返回值将被丢弃。new 表达式的结果仍然是this所引用的对象。
//当函数显式写了返回值为原始数据类型时,
//1.当使用new之后,函数(包括构造函数)返回原this对象,该对象的constructor(该属性继承自该函数的原型对象)指向着该函数。
//2.在普通函数调用下,返回显式的return值
function test()
{
this.a=10;
return 1;
}
var m=new test(); //m为{a:10}对象,m.constructor --> function test(){...}
//m的constructor属性继承自test.propertype原型对象(每个函数都有着原型对象)
//m.__proto__ === test.propertype
var n=test();//n为1,其中 window.a = 10
console.log(m)//返回[Object]
console.log(n)//返回1.