JavaScritp知识
this
解析器在调用函数每次都会向函数内部传递一个隐含的参数,这个隐含的参数就是this,this指向的是一个对象,这个对象称之为函数执行的上下文对象。
根据函数的调用方式不同,this会指向不同的对象
- 以函数的形式调用,this永远都是windonw
- 以方法的形式调用,this就是调用方法的那个对象
函数方法调用:
function fun(){
console.log(this);
}
fun();
//Window
方法的形式调用
function fun(){
console.log(this);
}
var obj = {
name:"张三",
sayName:fun
};
obj.sayName();
//{name: "张三", sayName: ƒ}
其实用函数的形式调用函数,也是用方法调用,fun()
相当于window.fun()
function fun(){
console.log(this.name);
}
var obj = {
name:"张三",
sayName:fun
};
var name = "李四"; //声明一个全局变量,其实也是调用了window.name方法并赋值
fun();
obj.sayName();
//李四
//张三
工厂方法创建对象
function People(name ,age, gander){
obj = new Object();
obj.name = name;
obj.age = age;
obj.gander = gander;
obj.Sayname = function(){
alert(obj.name)
}
return obj;
}
var obj1 = People("张三",18,"男");
var obj2 = People("李四",52,"男");
console.log(obj1);
console.log(obj2);
//
//{name: "张三", age: 18, gander: "男", Sayname: ƒ}
//{name: "李四", age: 52, gander: "男", Sayname: ƒ}
使用工厂办法创建的对象,使用的构造函数都是object
所以创建的对象都是object类型,就导致无法区分多种不同类型的对象
构造函数
创造一个构造函数,专门用来创建Person对象,构造函数就是一个普通函数,创建方式和普通函数没有区别,不同的是构造函数习惯上首字母大写
function Person(name,age){
this.name = name;
this.age = age;
}
var per = new Person('张三',18);
var son = new Person('李四',23);
console.log(per);
console.log(son);
//Person {name: "张三", age: 18}
//Person {name: "李四", age: 23}
构造函数的执行流程:
- 立刻创建一个新的对象
- 将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建的对象
- 逐行执行函数中的代码
- 将新建的对象作为放回值返回
可以使用instanceof检查一个对象是否是一个类的实例
console.log(per instanceof Person);
//true
原型对象prototype
创建的每一个函数,解析器都会想函数中添加一个属性prototype,这个属性对应着一个对象,这个对象就是所谓的原型对象。
如果函数作为普通函数调用prototype没有任何作用,当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,都可以通过__proto__来访问属性
function Person() {
//向Person的原型中添加一个属性a
Person.prototype.a = 123;
//向Person的原型中添加一个方法
Person.prototype.sayHello = function(){
alert("hello world!")
}
}
var per = new Person();
console.log(Person.prototype);
console.log(per.__proto__.a);
//{a: 123, sayHello: ƒ, constructor: ƒ}
//123
以后创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,这样不用为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法。
在上述中,此时可以用于检查per中是否真的有Myname属性
function Person() {
}
Person.prototype.Myname = "我是原型中的name";
var per = new Person();
console.log(Person.prototype.Myname);
console.log("Mynae" in per);
//我是原型中的name
//true
其实per属性中并没有Myname属性,而是原型对象中有Myname属性,但是in方法也返回了一个true,需要一个方法来检查per中是否有想要的属性,这个方法就是hasOwnProperty
原型对象也是对象,所以它也有原型对象。