JavaScript(五)[this、工厂方法创建对象、构造函数]

目录导航


this

//1. 设置一个全局变量name
	var name = '全局的name属性';
//2.访问 name 
	console.log(name);    // 全局的name属性
//3.定义一个函数
function fn(){
	console.log(name);    // 全局的name属性(根据作用域原理,进入全局找)
}
//4. 定义两个对象
	var obj = {
	name:"孙悟空",
	sayHello:fn
}

var obj2 = {
	name:"猪八戒",
	sayHello:fn
}

/*
obj.sayHello ===  fn()   ===   obj2.sayHello
obj.sayHello()      //全局的name属性
obj2.sayHello()     //全局的name属性
fn()                //全局的name属性
三个调用的是同一个函数
*/
要求: (调用了同一个函数,但结果不同)
调用obj.sayHello()  ----->  孙悟空
调用obj2.sayHello() ----->  猪八戒
调用 fn()           ----->  全局的name属性

/*
在调用函数时,浏览器每次都会向函数中传递一个隐式的参数
	--- 这个参数的名字就叫this,this指向的是一个对象
*/
function fn(){
   // 浏览器向函数中传了一个this参数
	console.log(this);  // window
}
//fn();  括号里没有传参数
fn();             --->   window{...}
obj.sayHello();   --->   {name:'孙悟空',sayHello:fn}
obj2.sayHello();  --->   {name:'猪八戒',sayHello:fn}
/*
	1.当以函数的形式调用一个函数时,this是window
	2.当以方法的形式调用一个函数时,this是调用方法的对象
*/

function fn(){
	//当name改成this.name
	console.log(this.name);
}
// 结果满足要求
fn();             //全局的name属性
obj.sayHello();   //孙悟空
obj2.sayHello();  //猪八戒

所以 this 是谁调用了他,this就是谁。

练习:

let name = "沙和尚";
let obj3 = {
	name:"孙悟空",
	sayHello:function(){
		console.log(name);
	}
};
// 调用结果是什么
obj3.sayHello();

/*
function 中寻找变量 name , 当 function 中没有 name 时,就往这个函数的上一层找,
而孙悟空的 name 是 obj 这个对象的属性,全称应该是 obj.name ,所以就到全局中去找 name , 
所以 obj3.sayHello(); 调用的结果是  沙和尚
*/

let name = "沙和尚";
let obj3 = {
	name:"孙悟空",
	sayHello:function(){
	// 这时的结果才是孙悟空,输出的 this 的属性,而且这里 this 指向了 obj3,因为是 obj3 调用了它。
		console.log(this.name);
	}
};

obj3.sayHello();

工厂方法创建对象

// 1.创建一个函数
function fn(name,age,gender,address){  //5.设置参数

	//2.创建一个对象
	let obj = {};
	
	//3.向对象中添加要的属性
	obj.name = name;          //  可直接写 name
	obj.age  = age;           //  可直接写 age
	obj.gender = gender;      //  可直接写 gender
	obj.address = address;    //  可直接写 address
	
	//4. 将对象作为返回值返回
	return obj;
}

//6.调用函数
let per1 = fn("孙悟空",18,"男","花果山");
let per2 = fn("猪八戒",28,"男","高老庄");
let per3 = fn("沙和尚",38,"男","流沙河");
let per4 = fn("唐三藏",48,"男","长安城");

//7.输出
console.log(per1);  // {name:"孙悟空",age:18,gender:"男",address:"花果山"}
console.log(per2);  // {name:"猪八戒",age:28,gender:"男",address:"高老庄"}
console.log(per3);  // {name:"沙和尚",age:38,gender:"男",address:"流沙河"}
console.log(per4);  // {name:"唐三藏",age:48,gender:"男",address:"长安城"}

构造函数

构造函数就是专门用来创建对象的函数
构造函数的定义的方式和普通函数没有区别
唯一的不同点在于构造函数的名字首字母要大写(非强制)

构造函数和普通函数区别在于调用方式
一个函数直接调用,那么它就是一个普通函数
构造函数使用 new 关键字调用
function fn(){
}
fu();         // 普通函数调用
new fn();     // 构造函数调用

构造函数执行流程:
1.创建一个新的对象

function Fn(){
	1.1// 函数中没有返回值
}
let per = new Fn();  1.3//  1.1中没有返回值,1.2有新的对象就是 new 关键字完成的
console.log(per);    1.2// 输出时得到的是一个新的对象 fn {}

2.将新的对象设置为函数中的 this

function Fn(){
	// 在构造函数中打印 this
	console.log(this);  // this 表示的就是新建的对象
	// 直接往 this 中添加,就是往新的对象中添加
	this.name = "孙悟空";
	this.age  =  18
}
let per = new Fn();    // per 创建了构造函数,所以 this 就是指 per
console.log(per);      // Fn{name:"孙悟空", age: 18}

3.执行函数中的代码
4.将新创建的对象返回
function Fn(name){
   this.name = name;
}

function Dog(name){
   this.name = name;
}

let per  = new Fn ("孙悟空");
let per2 = new Fn ("猪八戒");
let per3 = new Dog("大黄狗"); 
console.log(per);     //  Fn {name:"孙悟空"} 
console.log(per2);    //  Fn {name:"猪八戒"} 
console.log(per3);    //  Dog{name:"大黄狗"} 

向类中添加方法:
//定义一个表示人类的类
function Person(name,age){
	this.name = name;
	this.age = age;
	
	//添加一个方法
	this.sayHello = function(){
		console.log("大家好我是" + this.name);
	}
}
// 创建一个实例
let per = new Person("孙悟空",18)
//调用
per.sayHello();   // 大家好我是孙悟空

/*
方法直接定义在构造函数中,构造函数每执行一次,创建一个新的函数对象中,
每一个对象都有不同的sayHello()方法,但是这些sayHello()方法的功能是一样的
而创建许多会占用大量的内存空间,实际可以共用一个。
*/
// 将 sayHello 定义为全局函数
// 缺点:污染全局的命名空间,在全局中可能被覆盖
function sayHello(){
		console.log("大家好我是" + this.name);
	}
function Person(name,age){
	this.name = name;
	this.age = age;
	
	//将全局的 sayHello 方法赋值给它
	this.sayHello = sayHello;
}
let per = new Person("孙悟空",18)
per.sayHello();   // 大家好我是孙悟空

函数中没有返回值调用区别

function fn(){
   // 函数中没有返回值
}
//普通函数调用
let per = fn();
// fn 把返回值赋值给 per ,fn 函数中没有返回值, 所以 per 是 undefined
conso.log(per);   //    undefined 

//构造函数调用
let per = new fn();
//  输出 new 创建的新对象
console.log(per);    //  fn {} 

一个构造函数也称为是一个类,通过该构造函数创建的对象称为该类实例

function Fn(name){
   this.name = name;
}

function Dog(name){
   this.name = name;
}
// per1 和 per2 是 new Fn 创建出来的,所以 per1 和 per2 都是 Fn 的实例
// 因为这两个都是 Fn 这个类创建的 
// 通过同一个类创建的对象,称为同一类对象
let per1  = new Fn ("孙悟空");
let per2  = new Fn ("猪八戒");
// Dog 则不是同类创建的
let per3  = new Dog("大黄狗");

 instanceof   用来检查一个对象是否是一个类的实例
 语法:
 	对象 instanceof (构造函数)
	//per1 是不是 Fn 的实例
	//如果是类的实例则返回 true 反之返回 false
	console.log(per1 instanceof Fn)  // true
	console.log(per3 instanceof Fn)  // false
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值