JS高级二

2020.11.29

01.原型链的关系

原型链
①.实例对象通过关键字new和构造函数来创建
②.实例对象通过constructor属性来找到实例化自己的构造函数
③.构造函数通过prototype属性来找到自己的prototype属性
④.实例对象的__proto__指向实例化自己的构造函数的prototype
⑤.一个对象的__proto__指向构造函数的prototype,因为prototype自身又是一个对象,也有__proto__属性,如果prototype.__proto__指向Object.prototype,说明这个对象是单一的独立的,不是继承而来的
⑥.object.prototype的构造函数是Object
⑦.通过最外层的Object拿到实例化对象==>通过new重新创建==>new Object(实例化对象)
⑧.通过最外层的Object拿到构造函数的prototype==>通过new重新创建==>new Object(构造函数.prototype)

原型链:当从一个对象那里调取属性或方法时,如果该对象自身不存在这样的属性或者方法,就会去关联的prototype那里寻找,如果prototype没有,就会去prototype关联的prototype那里寻找。如果还没有,会一直向上寻找,直到prototype…prototype…为null。从而形成了原型链(根本上来说就是继承)

判断a是否存在于b的原型链中==>a.isPrototypeOf(b)
好处:可以判断对象的关联性

/*
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
语法:Object.create(proto, [propertiesObject])
*/
var person={
	name:'zs'
}
//通过person创建对象student。类似于继承
var student=Object.create(person);

案例:判断原型链存在关系

var person={
	name:'zs'
}
var student=Object.create(person);
var teacher=Object.create(student);
console.log(teacher.isPrototypeOf(teacher));//false
console.log(student.isPrototypeOf(teacher));//true
console.log(person.isPrototypeOf(teacher));//true
console.log(Object.prototype.isPrototypeOf(person));//true

/*分析:
关系:obj==>person==>student==>teacher
自身不能说存在于自身的原型链中==>false
在上面的存在于下面的原型链中,所以Object.prototype、person、student都存在于teacher的原型链中==>true
*/

a.hasOwnProperty(b)判断b属性是a自有的还是继承过来的

var person={
	name:'zs'
}
var student=Object.create(person);
var teacher=Object.create(student);
student.zid=101;
console.log(teacher.zid);//101
console.log(teacher.hasOwnProperty('zid'));//false,因为teacher.zid=101是从student继承来的


teacher.zid=001;
console.log(teacher.zid);//001
console.log(teacher.hasOwnProperty('zid'));//true,自有属性
// 如果一个对象既有自有属性,又可以继承。以自有属性为准

02.get和set

封装一个获取和设置的方法

var circle={
	r:20,
	// get获取值 get+空格+变量名  
	// set设置值 set+空格+变量名
	get acr(){
		return Math.PI*this.r*this.r;
	},
	set acr(value){
		this.r=value;
	}
}
// 如果是赋值,自动调用set方法
circle.acr=100;

// 如果是获取值,自动调用get方法
console.log(circle.acr);//3.1415*100*100=31415

03.属性特征

//正常赋值,属性可以直接修改,属性可以被遍历出来
var stu={
	name:'zs'
}
stu.name='小明';
for(var i in stu){
	console.log(i);//name
}


//某些属性比较重要,单独设置,一般特殊情况才这样使用
//设置属性的时候,可以配置属性特征
Object.defineProperty(stu,'password',{
	//password的值
	value:123,
	//是否可以被修改,true可以修改,false不可修改,默认值false
	writable:true,
	//是否可以被遍历,true可以遍历,false不可遍历,默认值false
	enumerable:true,
	//是否可以被重新配置,true可以重新配置,false不可重新配置,默认值false
	configurable:true
});

04.变量提升

案例1

console.log(a);
var a=10;//undefined
/*等价于
var a=10;
console.log(a);
a=10;
*/

如果一个变量声明,会把声明提升到整个作用域的最前面,赋值还是在原来的位置

案例2

console.log(a)
a=10;//报错 a is not defined
//a没有声明,在赋值之前没有办法直接使用
/*
a=10;
console.log(a);//10
*/

如果变量没有声明,作用域是赋值以后的区域

案例3

add();
function add(){
	console.log(111);//111
}
/*等价于
function add(){
	console.log(111);//111
}
add();
*/

通过该方法定义函数,会把整个函数提升到作用域最前面。

案例4

add();//报错 add is not a function
var add=function(){
	console.log(111);
}
/*等价于
var add;
add();//报错 add is not a function
add=function(){
	console.log(111);
}
*/

通过以下方法定义函数,只会把变量的定义提升到作用域最前面

案例5

var a=10;
function add(){
	console.log(a);//10
}
add();
/*等价于
var a;
a=10;
function add(){
	console.log(a);
}
add();
*/
var a=10;
function add(){
	console.log(a);//undefined
	var a=100;
}
add();
/*等价于
var a;
a=10;
function add(){
	//a的作用域在add的{}内
	var a;
	//按照就近原则找到上一行新声明的a,a只是声明了但未赋值==>undefined
	console.log(a);
	a=100;
}
add();
*/

变量提升,会把变量声明提升到整个作用域最前面。js中只有函数的作用域,变量的作用域,是向上寻找距离其最近的开始的函数的{变量的作用范围就是该{}以内。

案例6

function add(){
	var a=100;
}
add();
console.log(a);//报错 a is not defined
//a的作用域在add内,在外面操作就会报错

案例7

function add(){
	a=100;
}
//console.log(a);//add执行前输出,报错 a is not defined
add();//如果不执行add(),就会报错
console.log(a);//add执行后输出,100

执行函数相当于给变量赋值。变量没有声明,作用域是赋值以后都可以使用 。如果不执行函数,相当于不会执行赋值语句,此时进行操作(输出/赋值等)会报错。

05.作用域和作用域链

作用域:在js(暂不包括es6)中只有函数的作用域,在函数内部声明的变量,才能称为局部变量。全局和局部只是相对来说
作用域链:在某个作用域内使用变量的时候,首先会在该作用域内寻找该变量,如果没有,会一直向上寻找。这样的一种链式关系就是作用域链。其实指的就是变量的就近原则。

例如:

var m=10;
function add(){
	function mul(){
		//mul里没有m,向上在add里寻找,add里也没有,再向上,找到m=10
		console.log(m);//10
	}
	mul();
}
add();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值