01 构造函数内部设置方法(函数传值)函数传值:可以把构造函数的对象方法抽取为参数
<script>
//001 创建一个构造函数
function Person(name,age,toDoSomeThing) {
//002 在构造函数内部设置对象的属性和方法
this.name = name;
this.age = age;
this.sayName = function () {
console.log(this.name);
};
this.toDoSomeThing = toDoSomeThing;
}
//003 使用构造函数创建对象
var zhangsan = new Person("张三",18,function () {
console.log("张三在读书");
});
var lisi = new Person("李四",20,function () {
console.log("李四在玩耍");
});
//004 打印对象的属性
console.log(zhangsan.name);
console.log(zhangsan.age);
console.log(lisi.name);
console.log(lisi.age);
//005 调用对象的方法
console.log("__________________");
zhangsan.sayName();
zhangsan.toDoSomeThing();
lisi.sayName();
lisi.toDoSomeThing();
</script>
02 对象类型
检查对象的类型:instanceOf 获取对象的类型:Object.prototype.toString.call(dog)
-
对象的构造器属性
function Dog(name) {
this.name = name;
this.color = "黄色";
}
console.log(dog.constructor);
** 属性的名称:constructor**
** 属性的作用:指向创建该对象的构造函数,类似于现实生活中所有的产品都标有生产厂家一样**
-
构造函数的调用
-
01 构造函数可以像普通函数一样不通过new关键字直接调用
-
02 在使用构造函数创建对象的时候,如果没有传递参数,则()可以省略
-
代码示例
//01 创建构造函数
function Person() {
this.name = "张三";
this.age = 20;
this.sayName = function () {
console.log(this.name);
}
}
//02 使用构造函数创建对象
var p1 = new Person();
var p2 = new Person; //说明:如果不需要传递参数,则在调用构造函数的时候()可以省略
-
this
-
01 如果使用new 构造函数的方式调用,则this指向内部默认创建出来的空对象
-
02 如果像调用普通函数一样调用构造函数,则this指向全局对象window(不要这样使用)
-
<script>
//01 获得内置对象的类型
var obj = {};
console.log(obj.toString());
var arr = [];
console.log(arr.toString()); //无法获取正确的输出
console.log(Object.prototype.toString.call(arr)); //[object Array]
//02 创建构造函数
function Dog() {
this.name = "阿黄";
this.color = "黄色";
}
//03 使用构造函数创建对象
var dog = new Dog();
//04 获得构造函数创建的对象的类型
console.log(Object.prototype.toString.call(dog)); //[object Object] 并非Dog类型
//思考:为什么dog对象的类型不是Dog?
//解答:回想构造函数的执行过程,构造函数生成的对象是通过new Object()方式创建后赋值给this的,因此其类型为Object
//instanceOf 用于检查对象的类型
</script>
03 对象的类型检查和构造属性
<script>
//01 创建两个构造函数,分别用来构造Dog对象和Cat对象
function Dog(name) {
this.name = name;
this.color = "黄色";
}
function Cat(name) {
this.name = name;
this.color = "黑色";
}
//02 创建具体的对象
var dog = new Dog("阿黄");
var cat = new Cat("小花");
//03 验证dog和cat对象都是Object类型的
console.log(dog instanceof Object); //true
console.log(cat instanceof Object); //true
console.log(dog instanceof Dog); //true
console.log(dog instanceof Cat); //false
console.log(cat instanceof Cat); //true
console.log(cat instanceof Dog); //false
//04 对象中的构造属性
console.log(dog.constructor); //该属性指向创建该对象的构造函数(类似于现实生活中所有的产品都标有生产厂家一样)
console.log(cat.constructor);
//console.log(dog.constructor.constructor); //Function 函数的构造函数是Function
//console.log(Dog.constructor.constructor); //Function 的构造函数是本身
console.log(Object.constructor); //Function
</script>
示例:
<script>
//01 创建构造函数
function Person() {
this.name = "张三";
this.age = 20;
this.sayName = function () {
console.log(this.name);
}
}
//02 使用构造函数创建对象
var p1 = new Person();
var p2 = new Person; //说明:如果不需要传递参数,则在调用构造函数的时候()可以省略
console.log(p1.name);
console.log(p2.name);
//03 直接调用构造函数
//构造函数可以不通过关键new调用(注意:这是一种错误的演示)
Person();
console.log(window.name); //张三
window.sayName(); //张三
//总结:如果通过new关键字调用构造函数,则this指向的是新创建出来的对象
// 如果像调用普通函数一样调用构造函数,则this指向的是window全局对象
// 因为在构造函数内部并为创建任何新的对象,this上面设置的属性和方法此时会被附加到window上面
// 要谨防不通过new关键字直接调用构造函数
//04
function Person() {
this.name = "张三";
this.age = 20;
this.sayName = function () {
console.log(this.name);
}
}
</script>
总结:
如果通过new关键字调用构造函数,则this指向的是新创建出来的对象
如果像调用普通函数一样调用构造函数,则this指向的是window全局对象
因为在构造函数内部并为创建任何新的对象,this上面设置的属性和方法此时会被附加到window上面
要谨防不通过new关键字直接调用构造函数
–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
-
构造函数创建对象存在的问题
<script>
//代码示例:提供一个构造函数,用于创建人对象,需要包含以下属性和方法
//属性:学号、姓名、年龄
//行为:吃饭、阅读
//01 提供构造函数
function Student(number,name,age) {
//02 设置对象的属性
this.number = number;
this.name = name;
this.age = age;
//03 设置对象的方法
this.eat = function () {
console.log("eat");
};
this.read = function () {
console.log("阅读");
}
}
//04 创建学生对象
var stu1 = new Student("20170201","张佳佳",18);
var stu2 = new Student("20170202","刘小溪",20);
//05 比较并验证对象的方法
//说明:
console.log(stu1.eat == stu2.eat); //打印结果为false,说明每次创建对象,都会重新创建函数
//问题:如果创建的对象数量很多,而对象方法内部的实现一模一样,则造成了资源浪费
</script>
-
解决因每次都会创建新的函数而造成的资源浪费问题
<script>
//01 提供构造函数
function Student(number,name,age) {
//02 设置对象的属性
this.number = number;
this.name = name;
this.age = age;
//03 设置对象的方法
this.eat = eatFunction;
this.read = function () {
console.log("阅读");
}
}
var eatFunction = function () {
console.log("eat");
};
//04 创建具体的学生对象
var stu1 = new Student("20170201","张佳佳",18);
var stu2 = new Student("20170202","刘小溪",20);
//05 比较并验证多个对象是否实现方法的共享
console.log(stu1.eat == stu2.eat); //true
//尝试让所有的对象共用一个方法,在构造函数外部先定义好指定的函数,然后将该指定的函数赋值给函数内部的方法
//06 == 等于符号补充
//等于符号在进行比较的时候,只会比较值是否相等
//在比较基本数据类型的时候,比较变量(表达式)对应的值[具体的数据]是否相等
//在比较引用数据类型的时候,比较对象对应的值(引用地址)是否相等
</script>
-
新的问题
① 全局变量增多,造成污染
② 代码结构混乱,不易维护
③ 函数可以不通过对象直接调用,封装性不好
网友评论