js 高级

本文深入探讨JavaScript中的作用域概念,解释全局变量与局部变量的差异,以及未声明变量如何成为全局变量。同时,通过示例阐述了闭包的本质,指出闭包并非函数嵌套,且其内部函数可以访问外部变量。最后,讲解了原型和原型链的概念,展示了如何通过原型链实现方法的共享,并讨论了原型对象在面向对象编程中的角色和作用。
摘要由CSDN通过智能技术生成

1.js作用域

<script>
			//函数外声明定义的变量就是全局变量
			//网页中所有脚本和函数均可使用
			var quanju="全局变量";
			function  test1(){
				//name变量在test1函数中
				//name变量是局部变量
				//局部变量的作用域只能在当前函数中
				//每一个函数中都可以声明定义名称相同的变量,而不被影响
				var name="zhangsan";
				//window.alert("name=="+name);
				window.alert("quanju=="+quanju);
			}
			function test2(){
				var name="lisi";
				//window.alert("name=="+name);
				window.alert("quanju=="+quanju);
			}
			
			//如果变量在函数内没有声明(没有使用 var 关键字),该变量为全局变量。
			function test3(){
				testname="没有声明的变量"; //是window对象的变量【全局变量】
				//window.alert("testname=="+testname);
			}
			function test4(){
				window.alert("testname=="+testname);
			}
			//test1();
			//test2();
			//test3();
			//test4();
			
			//函数参数只在函数内起作用,是局部变量。
			function test5(myname){
				window.alert("myname=="+myname);
			}
			function test6(){
				window.alert("myname=="+myname);
			}
			//test5("张三");
			//test6("张三");
			//你的全局变量,或者函数,可以覆盖 window 对象的变量或者函数。
			window.doxname="dox"; // window 对象的变量
			var doxname="hello"; //全局变量
			function test7(){
				//全局变量会覆盖window 对象的变量
				window.alert("doxname=="+doxname);
			}
			//test7();
			//局部变量,包括 window 对象可以覆盖全局变量和函数。
			function test8(){
				var doxname="你好"; //局部变量
				//局部变量可以覆盖window 对象变量和函数也可以覆盖全局变量和函数
				window.alert("doxname=="+doxname);
			}
			 test8();
</script>

2.闭包

「函数」和「函数内部能访问到的变量」的总和,就是一个闭包
错误的认识:1.闭包不是函数套函数
错误的认识:2.闭包中的函数是可以没有return语句

<script>
			
			function test1(){
				var local="变量"; //局部变量
				function foo(){
					return local;
				}
				return foo;
			}
			
			function test2(){
				//调用test1函数,得到foo函数,被t1接收
				var  t1=test1();
				//调用t1就是就是访问foo函数
				var val=t1();
				alert(val);
			}
			test2();
			
</script>

3.原型和原型链

<script>
			/*
			var arr1 = [1, 0, 0, 8, 6];
			var arr2 = [1, 0, 0, 8, 6, 1, 1];
			arr1.sort(function(n1, n2) {
				return n1 - n2;
			});
			arr2.sort(function(n1, n2) {
				return n1 - n2;
			});
			console.log(arr1); //[0, 0, 1, 6, 8]
			console.log(arr2); //[0, 0, 1, 1, 1, 6, 8]
			console.log(arr1 === arr2);//false
			console.log(arr1.sort === arr2.sort);//true
			*/
			//上述代码中console.log(arr1 === arr2);为false,因为
			//arr1和arr2中的元素和元素个数不同。
			//console.log(arr1.sort === arr2.sort);为true,因为
			//arr1和arr2使用的是相同的sort方法,sort方法是arr1和arr2的公共方法
			//JavaScript是如何做到让sort方法是arr1和arr2的公共方法?
			/*
			var arr1 = [1, 0, 0, 8, 6];
			var arr2 = [1, 0, 0, 8, 6, 1, 1];
			//数组求和方法
			arr1.getSum = function() {
				var sum = 0;
				for(var i = 0; i < this.length; i++) {
					sum += this[i];
				}
				return sum;
			}
			//console.log(arr1.getSum()); //输出15
			//console.log(arr2.getSum());//控制台报错: Uncaught TypeError: arr2.getSum is not a function
			*/
		   
			//console.log(arr2.getSum());输出错误,因为
			//因为你的变量arr2没有getSum()方法。
			//那么有没有解决方案,函数只定义一次,然后提供给不同的变量使用呢?
			//答案是有的。
			
			var arr1 = [1, 0, 0, 8, 6];
			var arr2 = [1, 0, 0, 8, 6, 1, 1];
			//将getSum定义为原型方法
			Array.prototype.getSum = function() {
				var sum = 0;
				for(var i = 0; i < this.length; i++) {
					sum += this[i];
				}
				return sum;
			}
			console.log(arr1.getSum()); //控制台输出15
			console.log(arr2.getSum()); //控制台输出17
			
			//Array.prototype.getSum = function() {......}将getSum()方法给了Array.prototype
			//此时getSum()方法就成了原型方法,由此可知Array.prototype是数组的原型对象。
			//得到的结果是对象arr1和arr2就可以共享getSum方法了。
			
			//OOP---面向对象程序设计
			//在OOP的计算机编程架构中,首先需要创建一个类,然后有这个类来创建对象。
			/* java 实例
			public  class  Student{
				int age=23; //类中定义属性
				public void  test1(){  类中定义方法
					
				}
			}
			Student  stu1=new Student(); //通过上面的Student类创建对象stu1
			//如果创建对象的类中有属性和方法,那么在通过这个类创建对象的时候,
			//类中有属性和方法会被复制给创建的这个对象。
			*/
		   //我们现在认为student()----类
			function student(){
				this.name="zhangsan";
				this.test1=function(){
					
				}
			}
			//创建实例
			var  stu1=new student();
			//在 JavaScript 中不会把类中的属性和方法复制给实例
			//而是在对象实例stu1和它的构造器【student()】之间建立一个链接【__proto__属性】,
			//__proto__属性是从构造函数的prototype属性派生的。
			//之后通过上溯原型链,在构造器中找到这些属性和方法。
			//alert(stu1.__proto__); //[object Object]
			//alert(student.prototype); //[object Object]
			//函数上面都有一个属性(prototype),prototype属性指向了函数的原型对象(函数名称.prototype)。
			//即使你只定义了一个空函数,也存在一个prototype的属性。
			//例子尽管我们什么都不做,但是浏览器已经在内存中创建了两个对象:
			//student()[函数]和student.prototype,其中,我们称student为构造函数,因为我们后面要用到这个函数来
			// new对象,student.prototype称为Person的原型对象,简称原型。
			//alert(stu1.constructor);
			student.prototype.age=23;
			var  stu2=new student();
			alert(stu2.age);
			alert(stu1.age);
			
	</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值