一:JS中的构造函数
在这里可以这样理解构造函数 ,即构造一个对象的函数就叫做构造函数;
1:那么我们使用构造函数的目的是构造一个对象 ,如何构造一个对象就是我下面要说的:
在JavaScript中,任何合法的函数都可以作为对象的构造函数,这包括系统内置的函数,
也包括自己定义的函数。
注意:(一旦函数被作为构造函数执行,他内部的this属性将引用函数本身;)
在我们一般的学习中,一般构造函数都没有返回值,因为构造函数的内部就是一些属性和方法的定义,
还有这些属性的初始化(或者说这些属性和方法只是初始化有this指针传递进来的对象),因此我们通常不需要返回值,
总的来说从形式上来看,一个函数被作为构造函数还是普通函数执行的唯一区别就是是否使用 new运算符;;4
下面举个小李子你就会很容易理解,就不做太多解释啦!
function Student(name,age,gender) {
this.name=name;
this.age=age;
this.gender=gender;
this.sayHello=function(){
console.log('你好:'+this.name);
};
//console.log(this);
}
//如果这两行代码执行的话会出现 ”Cannot read property 'sayHello' of undefined“的错误;
//因为此时的this指向是window,而window对象中并没有定义过sayHello这个方法;
//var stu1=Student('wang','20','man');
//stu1.sayHello();
//会正常执行,打印出:”你好:wang“;
//此时当前stu2对象内的this指针指向的是当前对象,因此可以访问到我们再调用构造函数传入的参数值
var stu2=new Student('wang','20','man');
stu2.sayHello();
console.log('程序结束!');
那么下面我们讨论一下返回值的情况分为函数的返回值是引用类型和值类型的两种情况:
(1);返回值为引用类型的函数
如果一个函数的返回值是引用类型(例如是:数组,对象,函数)的数据,那么这个函数被作为
构造函数用new运算符执行时,运算的结果将被他的返回值取代,这时,构造函数体内的this
即指向原构造函数构造出来的对象指针丢失了,此时返回的是被return 的对象;
function test() {
this.a=10;
return function(){
return 1;
};
}
var m =new test();
var n = test();
console.log(m());//打印出1;
console.log(n());//打印出1;
可以看到运行结果 m和n的值是一样的,都是test函数的闭包,而this引用的对象和this.a=10的赋值结果都 被丢弃;
(2)返回值为值为值类型的函数
如果一个函数的返回值是一个值类型,那么这个函数作为构造函数用new 运算符执行构造时,他的返回值将会被丢弃;
new 表达式的结果仍然是this所引用的对象;
function test() {
this.a=10;
return 1;
}
var m=new test();
//不使用new时,就是调用返回值为1 的test函数,this指针指向window,
//this.a相当于给window对象添加了一个a属性,且属性值为10;
var n =test();
console.log(m);//打印出:test { a: 10 }
console.log(n);//打印出:1
二:JS中的原型对象的理解
在JS中当我们创建一个新的函数时 ,同时也会自动为该函数创建一个prototype的属性,
这个属性指向函数的原型对象;
注意:在默认的情况下,所有的原型对象均会有一个constructor属性,这个属性也是一个指针 ,
指向构造函数;
所以可以这样看,构造函数的prototype属性指向原型对象,原型对象中的constructor属性指向构造函数;
下面来看这个例子:
//创建一个Person构造函数,(其实构造函数就是一个构造对象的函数,也就是一个不需要返回值的函数)
function Person() {}
//在构造函数的原型上面添加属性和方法
Person.prototype.name='wang';
Person.prototype.age=20;
Person.prototype.gender='man';
Person.prototype.SayHello=function(){
return '你好:'+this.name;
}
//实例化两个对象
var person1=new Person();
var person2=new Person();
console.log(person1.SayHello());//打印出:你好:wang
可以看到上面的第一行代码中,在Person构造函数中,其中除了默认的一个 prototype属性,并没有任何的属性和方法,
而且我们构造出来的person1实例上除了内部属性 [[prototype]],也是什么都没有,但是当我们
访问person1.sayHello的时候会有返回值呢?
以下是对这个问题的解释:
(1)当我们访问一个对象时,
如果该对象存在这个属性,则返回这个属性;
注意:(如果当前属性和原型上的属性相同时,则不会去访问原型对象上的属性 ,
如果想要去访问原型上的这个相同的属性,可以删除当前对象上的这个属性即可)
{
如果该对象不存在这个属性,则取这个对象上的原型上面去寻找,
{
如果原型上面存在这个属性,则返回这个属性的属性值;
如果原型上面不存在这个属性,则返回一个undefined;
}
}
(2)当我们为一个对象添加属性时,他首先会检查当前对象上是否存在这个属性 ;
如果没有,则添加这个属性并且进行赋值;(注意其不会去原型上去寻找zhe'ge')
如果有,则修改成你赋予的值;