This
- 解析器在调用函数每次都会像函数内部传递进一个隐含的参数
- 这个隐含的参数就是this,this指向的是一个对象
- 这个对象我们称之为函数执行的上下文对象
- 根据函数的调用方式的不同,this会指向不同的对象
1、以函数的形式调用,this永远都是window
2、以方法的形式调用时,this就是调用方法的那个对象
var name = "张三";
function fun() {
console.log(this.name);
}
//以函数的形式调用,this就是window
window.fun();
var obj = {
name:";李四",
age:18,
sayName:fun
}
//以方法的形式调用,this就是调用方法的对象
obj.sayName();
image.png
e.g
//创建一个name的变量
var name = "全局";
//创建一个fun()函数
function fun() {
console.log(this.name);
}
//创建俩个对象
var obj = {
name:"张三",
sayName:fun
}
var obj2 = {
name:"李四",
sayName:fun
}
fun();
obj.sayName();
image.png
使用工厂方式创建对象
- 使用工厂方法创建对象,该方法可以大批量的创建对象
function creatPerson(name,age,gender) {
// 创建一个新的对象
var obj = new Object();
// 向对象中添加属性
// 不能写死了
// obj.name = "孙悟空";
obj.name = name;
// obj.age = 18;
obj.age = age;
// obj.gender = "男";
obj.gender = gender;
obj.sayName = function () {
alert(this.name);
};
return obj;
}
var obj2 = creatPerson("孙悟空",18,"男");
var obj3 = creatPerson("猪八戒",18,"男");
var obj4 = creatPerson("沙和尚",18,"男");
console.log(obj2);
console.log(obj3);
console.log(obj4);
alert(obj4.sayName());
image.png
构造函数
- 创建一个构造函数,专门用来创建Person对象的,
- 构造函数就是一个普通的函数,创建方式和普通函数没有区别
- 不同的是构造函数习惯首字母大写
- 构造函数和普通函数的区别就是调用方式的不同
- 普通函数就是直接调用,而构造函数需要new关键字来调用
- 构造函数的执行流程:
1、立刻创建一个新的对象
2、将新建的对象设置为函数中的 this,在构造函数中可以使用新建的this来引用新建的对象
3、逐行执行函数中的代码
4、将新建的对象作为返回值返回 - 使用同一个构造函数 创建的对象,我们称之为一类对象,也将一个构造函数称为一个类
- 我们将通过一个构造函数创建的对象,称之为该类的对象
-this的情况
1、当以函数的形式调用时,this是window
2、当以方法的形式调用时,谁调用方法this就是谁
3、当以构造函数的形式调用时,this就是新创建的那个对象
function Person(name,age,gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = function () {
console.log(this.name)
};
}
function Dog() {
}
var per2 = new Person("张三",18,"男");
var per3 = new Person("李四",24,"男");
var per4 = new Person("丽丽",15,"女");
var dog2 = new Dog();
console.log(per2);
console.log(per3);
console.log(per4);
console.log(dog2);
/*使用instanceof可以检查一个对象是否是一个类的实例
* 语法:
* 对象instanceof 构造函数
* 如果是,则返回true,否则返回false*/
console.log(per4 instanceof Person);
console.log(dog2 instanceof Dog)
image.png
构造函数修改
- 创建一个Person构造函数
- 在Person构造函数中,为每一个对象都添加了一个sayName方法
- 目前我们的方法是在构造函数内部创建的
- 也就是构造函数每执行一次就会创建一个新的sayName方法
- 也就是所有实例的sayName都是唯一的
- 这样就导致了构造函数每执行一次就会创建一个新的方法
- 执行1000次就创建1000个方法,而1000个方法都是一样的
function Person(name,age,gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = fun;
}
function fun() {
console.log(this.name)
};
var per2 = new Person("张三",18,"男");
console.log(per2);
image.png
原型对象
原型prototype
-
我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
-
这个属性对应着一个对象,这个对象就是我们所谓的原型对象
-
如果函数作为普通函数调用prototype没有任何作用
-
当函数以构造函数的形式调用时,他所创建的对象都会有一个隐含的属性
指向该构造函数的原型对象,我们可以通过proto来访问该属性 -
原型对象就相当于一个公共的区域,所有同一类的实例都可以访问到这个原型对象
我们可以将对象中共有的内容,统一设置到原型对象中 -
当我们访问对象的一个属性或者方法时,他会现在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用
-
以后我们创建构造函数时,可以将这些对象的共有属性和方法,统一添加到构造函数的原型对象中,这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了
-
向原型中添加sayName()方法
function Person(){
this.name = name;
}
Person.prototype.name = "我是原型中的名字";
Person.prototype.sayName = function(){
alert("Hello大家好,我是:"+this.name);
}
原型对象的原型
- 使用in检查对象是否含有某个属性时,如果对象中没有但是原型中有 也会返回true
console.log("name" in mc);
- 可以使用对象的 hasOwnProperty()来检查对象自身中是否含有该属性
- 使用该方法只有当对象自身中含有属性时,才会返回true
console.log(mc.hasOwnProperty("age"));
console.log(mc.hasOwnProperty("hasOwnProperty"));
- 原型对象也是对象,所以她也有原型
- 当我们使用一个对象方法或属性时,会在自身中寻找,
- 自身中如果有,则直接使用
- 如果没有则去原型对象中寻找,如果原型对象中有,则使用
- 如果没有,则去原型的原型中去寻找,直到找到object对象的原型,
- Object对象原型没有原型,如果在Object中依然没有找到,则返回undefined
console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));
image.png
image.png
image.png
网友评论