JS进阶知识——(二)函数高阶知识

本文详细介绍了JavaScript中的原型与原型链,包括显式和隐式原型,原型链的作用;探讨了执行上下文和上下文栈的概念,以及变量提升和函数提升的原理;此外,还深入讨论了闭包的原理、作用、生命周期和应用,并提供了面试题实例,帮助读者深化对JS高级知识的理解。
摘要由CSDN通过智能技术生成

JS进阶知识。


前言

这是函数的高级知识,主要涉及到JS原型链问题、执行上下文问题、作用域问题以及函数的闭包问题,是面试最常问到的JS考察点。

一、原型与原型链。

1.1 什么是原型(prototype)?

		<title></title>
	</head>
	<!--                                        
	 1、函数的prototype属性                        ↑
	 *每个函数都有一个Prototype属性 它默认指向一个object 空对象(即为原型对象)_
	 *原型对象中有一个属性 constructor 它默认指向函数对象
	 
	 2、给原型对象添加属性(一般都是作为方法添加)
	 *作用:所有的函数对象的实例对象自动拥有原型中的属性与方法;
		 
	 -->
	<body>
		<script type="text/javascript">
			console.log(Date.prototype)
			function Fun1(){
				
			}
			console.log(Fun1.prototype)//默认指向一个object空对象 没有属性
			
			console.log('________________________________')
			//原型对象中有一个属性 constructor 它默认指向函数对象
			console.log(Date.prototype.constructor === Date)
			console.log(Fun1.prototype.constructor === Fun1)
			
			//函数对象的实例对象自动拥有原型中的属性与方法;
			Fun1.prototype.test = function (){
				console.log('test()')
			}
			var fun1 = new Fun1();
			fun1.test();
		</script>

便于理解 关系如下图所示

 其实为了理解原型链 我们首先得了解并承认下列最基础的结论:

 我们继续。

1.2 什么是显式原型与隐式原型?

 

		<title></title>
		<!-- 
		 1.每个函数function 都有个prototype ,即为 显式原型(属性)
		 
		 2、每个实例对象都有一个__proto__, 即为  隐式原型(属性) 
		 
		 3、对象的隐式原型的值 等于 其构造函数的显式原型的值。
		***我们通过显式原型添加方法! 我们能直接通过显式原型直接操作它。
		但是我们不能直接操作隐式原型!!(ES6之前        -我们正在学习ES5);
		 -->
	</head>
	<body>
		<script type="text/javascript">
			function Fn(){//故创建函数对象的内部语句就是 this.prototype = {}
				
			}
			//1、每个函数function 都有一个prototype 显式原型
			console.log(Fn.prototype)
			//2、每个实例对象都有一个__proto__, 即为  隐式原型(属性) 
			var fun1 = new Fn ()//由后面往前推我们可以知道————
			//创建实例就是 this._proto__ = Fn.prototype   将原型函数的显示原型地址值赋值给了实例对象的隐式原型。
			console.log(fun1.__proto__)
			
			//3、对象的隐式原型的值 等于 其构造函数的显式原型的值。
			console.log(Fn.prototype === fun1.__proto__)//返回一个true;
			//两个都是引用类型的 变量保存的是 !地址值!  两个保存一样的地址 指向同一块 →原型对象;
			
			
		</script>

! 注意 在Chrome等多数浏览器中 在控制台查看对象属性时 __proto__ 一般以[[prototype]]存在。 

1.3 原型链:

<title></title>
		<!-- 
		 
		 -->
	</head>
	<body>
		<script type="text/javascript">
			function Fn (){
				this.test1  = function(){
					console.log('test1')
				}
			}
			Fn.prototype.test2 = function(){
				console.log('test2')
			}
			var fn = new Fn ()
			fn.test1()
			fn.test2()
			console.log(fn.toString())
			
			//fn的__proto__是FN.prototype   而后者的__proto__是 Object.prototype. 而再后者的__proto__找不到 返回undefined
			
			/*原型链————在访问一个对象的属性时 现在自身的属性中查找 没找到再去__proto__链上往原型对象里找
			如果最终找不到了 返回undefined(现在返回Null))别名*隐式原型链  作用 查找对象的属性与方法。
			构造函数 与 原型 与实体对象的关系图解!
			
			*/
		   console.log('______________________________________________')
		   console.log(Object.prototype.__proto__)
		   
		   /*原型链补充总结:
		   1*函数的显式原型指向的对象默认是空的Object实例对象(但是Object不满足 它的显式原型对象是)
		
		   */
		  console.log(Fn.prototype instanceof Object) //true
		  console.log(Object.prototype instanceof Object)//false 唯一例外
		  console.log(Function.prototype instanceof Object)//true
		  console.log('————————————————————————————————————————————————————————————————')
		  /* 2 Function 是它自身的实例。。 所有函数都是Function 的实例对象。
		    它是实例对象 有隐式原型↓              ↓ 它是自身的实例 有显式原型属性                                   */
		 console.log(Function.__proto__ === Function.prototype)//输出true
		 //Object的原型对象是原型链尽头 
		 console.log(Object.prototype.__proto__ === null)//找不到它的原型了
		</script>

更直观地 我们可以画出下列图 所有的原型链关系基本都可以在下图中找到对应关系:

 1.4 原型链属性问题:

<title></title>
	</head>
	<body>
		<script type="text/javascript">
			function Pers(){
				
			}
			Pers.prototype.name = 'mqy'
			var per1 = new Pers()
			console.log(per1.name,per1)//**这里来到Pers.prototype找到属性name并输出
			
			var per2 = new Pers()
			per2.name = 'yyy'//这里是为 per2函数添加了name属性 值为yyy
			console.log(per1.name)//仍然是‘mqy’没变 因为在自身per1里没有这个属性 就去原型链中找
			console.log(per2.name)//改变为'yyy'了; 因为在per2中已经找到了这个属性 不去原型链中找了。
			//总结:读取对象属性值时,会自动去原型链中查找,而再设置对象属性值时,不查找原型链 如果当前对象没有此属性 直接添加此属性
			
			console.log('——————————————再来看看属性—
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值