this、函数、prototype、toString(JS)
this
- 使用工厂方法创建函数
- 原型
prototype
toString
this
- 解析器在调用函数每次都会向函数内部传递进一个隐含的参数;这个隐含的参数就是this,this指向一个对象,这个对象我们成为函数执行的上下文对象,
- 根据函数的调用方式不同,this会指向不同的对象
- 以函数的形式调用时,this永远都是window
- 以方法的形式调用时,this就是调用方法的那个对象
function fun() {
// consolo.log("a = "+a+", b = "+b);
consolo.log(this);
}
// fun();
var obj = {
name = "sunwukong",
sayName = fun,
};
var obj2 = {
name = "zhubajie",
sayName = fun,
};
// consolo.log(obj.sayName == fun);
obj.sayName();
使用工厂方法创建对象
构造函数 (默认首字母大写)
-
普通函数直接调用,构造函数需要使用new关键字调用
-
构造函数的执行流程:
- 立刻创建一个新的对象
- 将新建的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象
- 逐行执行函数中的代码
- 将新建的对象作为返回值返回
-
使用同一个构造函数创建的对象,称为一类对象,也将一个构造函数称为一个类,我们将通过一个构造函数创建的对象,称为是该类的实例
- 使用instanceof可以检查一个对象是否是一个类的实例
语法:(对象 instanceof 构造函数)
- 使用instanceof可以检查一个对象是否是一个类的实例
-
this的情况:
- 当以函数的形式调用时,this是window
- 当以方法的形式调用时,谁调用方法this就是谁
- 当以构造函数的形式调用时,this就是新创建的那个对象
//使用工厂方法创建对象
function creatPerson(name, age, gender) {
var obj = new object();
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayName = function() {
alert(this.name);
};
return obj;
}
var obj1 = creatPerson("sunwukong", 18, "nan");
var obj2 = creatPerson("zhubajie", 28, "nan");
console.log(obj1);
console.log(obj2);
//构造函数
function Person(name, age, gender){
this.name = name;
this.age = age;
this.gender = gender;
// 向对象中添加一个方法
this.sayName = function () {
alert(this.name);
};
}
var per = new Person("sunwukong", 18, "nan");
var per2 = new Person("zhubajie", 28, "nan");
console.log(per instanceof Person);
//构造函数修改
//将sayName方法在全局作用域中定义
// 将函数定义在全局作用域,污染了全局作用域的命名空间,而且不安全;
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = fun;
}
function fun() {
alert("Hello 大家好,我是:"+this.name);
}
var per = new Person("蔡zhu", 18, "女");
var per2 = new Person("zhubajie", 28, "nan");
console.log(per.sayName == per2.sayName);
// per.sayName();
// per2.sayName();
原型 prototype
- 我们创建的每一个函数,解析器都会向函数中添加一个属性
prototype
,这个属性对应着一个对象,这个对象就是原型对象- 如果函数作为普通函数调用prototype没有任何作用
- 当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性
指向该构造函数的原型对象,可以通过__proto__
来访问该属性
- 原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,
我们可以将对象中共有的内容,统一设置到原型对象中 - 以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中。 这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法
*/
function MyClass(){
}
var mc = new MyClass();
var mc2 = new MyClass();
//向MyClass的原型中添加属性a
MyClass.prototype.a = 123;
//向mc中添加a属性
mc.a = "我是mc中的a";
//向MyClass的原型中添加一个方法
MyClass.prototype.sayHello = function() {
alert("hello");
};
console.log(mc.a); // 我是mc中的a
console.log(mc2.a); // 123
mc.sayHello();
// console.log(MyClass.prototype);
console.log(mc.__proto__ == MyClass.prototype); //true
//使用 in 检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
//console.log("a" in mc);
//可以使用对象的 hasOwnProperty() 来检查对象自身中是否含有该属性
//使用该方法只有当对象自身中含有属性时,才会返回true
console.log(mc.hasOwnProperty("a")); // true
toString
function Person (name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
var per = new Person("monkey", 18, "nan");
var per2 = new Person("pig", 12, "nv");
console.log(per); //返回 [object, object];
// 在对象中添加一个toString方法
per.toString = function() {
return "Person[name="+this.name+",age="+this.age+",gender="+this.gender+"]";
};
console.log(per); //返回 Person[name=monkey,age=18,gender=nan]
console.log(per2); //返回 [object, object]
//修改Person原型的toString
Person.prototype.toString = function () {
return "Person[name="+this.name+",age="+this.age+",gender="+this.gender+"]";
};
console.log(per); //返回 Person[name=monkey,age=18,gender=nan]
console.log(per2); //返回 Person[name=pig,age=12,gener=nv]