构造函数注意事项
- 01函数传值
- 02对象的类型(判断)
- 03构造器属性(获取)
- 04函数调用
- 05this
构造函数创建对象存在的问题
- 每创建一个对象,内部都会声明一个showName函数
01函数传值普通版
<script>
function Student(number, className){
this.number = number;
this.className = className;
this.log = function(){
console.log(this.number + '-' + this.className);
}
}
var stu1 = new Student('0001','王者荣耀01班');
var stu2 = new Student('0002','王者荣耀01班');
console.log(stu1);
console.log(stu2);
stu1.log();
stu2.log();
</script>
01函数传值升级版
<script>
function Student(number, className, log){
this.number = number;
this.className = className;
this.log = log;
}
var stu1 = new Student('0001','王者荣耀01班', function(){
console.log("hello hello hello" + '-' + this.number);
});
var stu2 = new Student('0002','王者荣耀01班', function(){
console.log("world world world" + '-' + this.className);
});
console.log(stu1);
console.log(stu2);
stu1.log();
stu2.log();
</script>
02 对象的类型(判断)
关键字 instanceOf
用来判断当前对象是否是某个类型的实例(检查某个对象是否是使用指定构造函数创建的)
语法: 对象 instanceOf 构造函数(类型)
<script>
function Person(){};
function Dog(){};
var p1 = new Person();
var dog1 = new Dog();
console.log(p1 instanceof Person); //true
console.log(p1 instanceof Dog); //false
console.log(dog1 instanceof Person); //false
console.log(dog1 instanceof Dog); //true
</script>
03 构造器属性(获取)
<script>
function Person(){};
function Dog(){};
var p1 = new Person();
var dog1 = new Dog();
console.log(p1.constructor); //Person
console.log(dog1.constructor);//Dog
</script>
04 函数调用
new :创建对象,并在最后返回该对象
构造函数:用于初始化对象
可以以普通函数的方式来调用构造函数(这是一个错误的演示,不要这样写代码)
<script>
function Person(name) {
this.name = name;
console.log(this);
}
var p1 = new Person("哈哈哈");
console.log(p1);
var p2 = Person('王者农药');
console.log(p2); //undefined
</script>
以上代码存在的问题
01 用调用普通函数的方式调用构造函数(没有报错)
02 打印p2,得到的是undefined
03 通过打印this,可以知道,用调用普通函数的方式调用构造函数,this属于window
为了解决以上代码存在的问题,需在构造函数中多加一层判断,如下
<script>
function Person(name) {
if(this instanceof Person){
this.name = name;
} else {
return new Person(name);
}
}
var p1 = new Person("哈哈哈");
console.log(p1);
var p2 = Person('王者农药');
console.log(p2); //Person
</script>
05 this
以普通函数的方式来调用构造函数,那么内部的this指向的是window,代码同上
<script>
function Person(name) {
if(this instanceof Person){
this.name = name;
} else {
return new Person(name);
}
}
var p1 = new Person("哈哈哈");
console.log(p1);
var p2 = Person('王者农药');
console.log(p2); //Person
</script>
构造函数创建对象存在的问题
- 每创建一个对象,内部都会声明一个showName函数
<script>
function Person(name,age){
this.name = name;
this.age = age;
this.showName = function(){
console.log("姓名:");
};
}
//创建对象
var p1 = new Person("张小花",18);
var p2 = new Person("张全蛋",99);
p1.showName();
p2.showName();
//每创建一个对象,内部都会声明一个showName函数
console.log(p1.showName == p2.showName); //false
</script>
-
在内存中的结构图
每创建一个对象,内部都会声明一个showName函数 -
优化方案(也存在问题)
问题:
01 把函数写在外部,破坏了封装性。
02 增加一个全局变量。
<script>
var showName = function(){
console.log("姓名:");
}
function Person(name,age){
this.name = name;
this.age = age;
this.showName = showName;
}
//创建对象
var p1 = new Person("张小花",18);
var p2 = new Person("张全蛋",99);
p1.showName();
p2.showName();
//每创建一个对象,内部都会声明一个showName函数
console.log(p1.showName == p2.showName); //true
</script>
-
在内存中的结构图
构造函数优化
终极版:原型解决构造函数创建对象的问题
<script>
function Person(name,age){
this.name = name;
this.age = age;
}
var p1 = new Person("张小花",18);
var p2 = new Person("张全蛋",99);
Person.prototype.showName =function (){
console.log("momo");
};
//设置原型对象的属性和方法的时候:构造函数.prototype.属性
//对象.prototype.属性
//创建对象
p1.showName();
p2.showName();
console.log(p1.showName == p2.showName);
</script>
网友评论