JS(四)中级

一、引言

思维角度:以一个Java开发的程序员的视觉,思考JS面向对象语言的特点

思考1:JS是面向对象的语言,但是没有类的概念,如何创建对象?

思考2:JS是面向对象的语言,但是没有类,怎么继承

二、解决问题

问题1:没有类,如何创建对象?

理解:JS虽然没有类库,也没有class,所以无法通过类的形式创建对象。但是,我们直到对象的本质无非是属性加上方法吗?

例1  一个对象的创建

     var animal={
	        	name:"animal",
	        	eat:function(){
	        		console.log(this.name+" is eating");//向控制台输出内容
	        	}
	        };
	        animal.eat();//调用函数

补充:由于对象的并并不和类关联,可以随意的给这个对象添加属性

例2  添加属性

        <script type="text/javascript">
	        var animal={
	        	name:"animal",
	        	eat:function(){
	        		console.log(this.name+" is eating");//向控制台输出内容
	        	}
	        };
	        animal.eat();
	        animal.color="black";//给对象添加新属性
	        console.log(animal.color);
	</script>

至此:对象创建出来了,但是对象太自由了(思考:弊端是什么?)

问题2:没有类怎么继承?

理解:继承无非是让类与类建立关联,那么如何建立关联呢?

关联方式:JS中的每一个对象都有一个特殊的属性"__proto__",通过此属性去关联另外一个对象,这个对象就是所谓的原型

例3

<script type="text/javascript">
	        //(1)创建一个对象(非new的形式)
	        var animal={
	        	name:"animal",
	        	eat:function(){
	        		console.log(this.name+" is eating");//向控制台输出内容
	        	}
	        };     
	        animal.color="black";//对象中添加一个属性
	        
	        //(2)创建一个对象
	        var dog={
	        	name:"dog",
	        	__proto__:animal //指向animal对象
	        };
	        //(3)创建一个对象
	        var cat={
	        	name:"cat",
	        	__proto__:animal //指向animal对象
	        };
	        dog.eat();//继承原型的方法
	        cat.eat();//继承原型的方法
	        console.log(dog.name);//dog   --覆盖原型的属性
	        console.log(cat.name);//cat   --覆盖原型的属性
	        console.log(cat.color);//black--继承原型的属性
</script>

分析:cat和dog对象的原型都是animal,但是其对象里面都没有定义eat方法,那么是如何调用的呢?

过程:当eat方法被调用时,首先会在自己(调用对象)的方法列表中寻找,如果找不到,则去原型中寻找,如果仍找不到继续往上

层的原型中去寻找,直到找到了Object那里,任然找不到,则就是未定义(undifined)。几个对象会通过__proto__建立如下的

型链(作用:函数复用)


回顾:JVM虚拟机中,一个对象在执行方法的时候,整个流程:也是先查找方法的定义,查找次序:先从本对象所属的类开始,

然后是父类,祖父类,直到Object,思路是一样的。

补充:关于JS属性的属性,也是如此通过原型链查询的

三、向Java靠拢

我们知道JS本来全名叫LiveScript,为了搭上Java帝国的快班车,改名为JavaScript,向Java示好。

模仿Java的类定义、创建对象、以及调用方法。

具体表现

例4

                        function Student(name){
				this.name=name,//也可以变成;号,但是JSON形式封装数据不行
				this.hello=function(){
					console.log("I am "+this.name);
				}
			}
			 var jane=new Student("jane");//创建对象(var可以省略!!!)
			 var tony=new Student("tony");//创建对象(hello定义在此对象中,意味着该对象有此方法的实体)
			 jane.hello();//I am jane
			 tony.hello();//I am tony

示好说明:提供了一个家叫做构造函数的东西,可以看到function有点类似class的感觉(雏形),并且有this关键字,而且Student

,整个感觉就像是一个Java类

上面出现小问题:每个新创建的对象都有一个hello函数,函数定义在对象上,意味着每个对象都有一份太浪费

高效的解决方法:把hello函数放到自己创建的原型对象中去,然后让jane、tony这些从Student中创建而来的对象指向这个原型

如何指向呢?把原型对象放到Student.prototype这个属性中

例5

<script type="text/javascript">   
			function Student(name){
				this.name=name;
			}
			//重点在这!!!
			Student.prototype={
				hello:function(){
					console.log("I am "+this.name);
				}
			}
			 var jane=new Student("jane");//创建对象
			 var tony=new Student("tony");//创建对象
			 jane.hello();//I am jane
			 tony.hello();//I am tony
</script>

特点:每次通过Student创建的对象(jane、tony),JS会自动建立原型链

具体分析:new Student的时候,JS会建立如下的关系链:


实质:所谓的构造函数Student就是一个幌子,每次通过"new Student"创建对象,并且把该对象的原型(__proto__)指向

Student.prototype这个原型对象,这样就能找到hello()方法。

理论基础:当一个对象调用方法的时候,会顺着原型链向上寻找。

四、向Java程序员示好(了解即可)

由于上述的构造函数再加上prototype的概念,让人很是费解,JS提供了一些语法糖来降低程序员(Java)的负担。

例6

                    //重点是class
			class Student(name){
				this.name=name,
				this.hello=function(){
					console.log("I am "+this.name);
				}
			}
			var jane=new Student("jane");//创建对象
			var tony=new Student("tony");//创建对象
			jane.hello();//I am jane
			tony.hello();//I am tony

说明:语法糖已经把JS变得非常像Java(C#、C++)的类了。

注意:class是ES 2015的新特性

思考:原型法对于Java、C#、C++码农不是很直观,引入类的语法糖能吸引更多的码农加入JS王国,但是JS是否远离了初衷?

四、JSON

理解JOSN封装数据是封装一种格式,这种格式也被其他语言也采用了 。

特点:JSON采用键值对的方式去封装数据(非二进制流);应用场景:JOSN数据占用比较小,一般用于网络传输、交换数据

说明:JSON中的引号括起来,如果是字符串也用引号括气来(数字不括)

应用1:标准JSON数组的遍历

<script type="text/javascript">
		//(1)定义JSON的数组对象
		    var JSON={
		    	name:"jane",
		    	age:18,
		    	agender:"male"
		    };
		    document.write(typeof JSON);
		//(2)遍历JSON数组--特有的for in的形式
		for(var i in JSON){
			console.log(JSON[i]);
		}
	         //表示遍历数组,而i表示的是数组的下标值,
                 //JSON[i]表示获得第i个数据
</script>

注意:for in循环的用法(里面参数的含义),普通的for循环方法

应用2:复杂的标准JSON格式的数组遍历(嵌套)

需求:获取相同JSON格式中的某个字段的内容

//(1)定义JSON的数组对象(嵌套)
	var JSON=[
	{"flag":1,"age":18,"phone":"110","userName":"小红"},
	{"flag":0,"age":20,"phone":"119","userName":"小明"}];
	//(2)遍历JSON数组--for in的形式
	for(var i in JSON){
		console.log(JSON[i].userName);
	//result[i]表示获得第i个json对象即JSONObject
        //result[i].字段名称--即可获得指定字段的值
}

应用3:复杂的非标准JSON格式的数组遍历(嵌套)

<script type="text/javascript">
		//(1)定义非标准的JSON的数组对象(嵌套)
		 var JSON = {
				"name": "张三",
				"age": 23,
				"sex": "男",
				"score": {
					"chinese": 100,
					"math": 90,
					"english":85
				}
			};
        //(2)遍历数据
        for(var i in JSON){
        	//重要:通过typeof 把object转成一个字符串的"object"
			var v = typeof JSON[i];
			if(v=="object"){
				//表明又是一个JSON格式的数据,则获取出这个嵌套的json对象 再次进行遍历
				var innerJSON= JSON[i];
				for(var j in innerJSON){
					console.log(innerJSON[j]);
				}
			}else{
				//说明是基本类型的数据
				console.log(JSON[i]);
			}
        }
</script>
	

应用4:复杂的非标准JSON格式的数组遍历(嵌套)

            var JSON={
			"datas":
			[{"flag":1,"macId":"2","mbId":0,"userName":"XXX"},
			{"flag":1,"macId":"1","mbId":1,"userName":"YYY"}]
			};
			//说明:进行遍历之前得先解析出标准的json数组格式即[{},{}]
			var json=JSON.datas;
			for(var i in json){
			//表示遍历数组,而i表示的是数组的下标值,
        		//data[i]表示获得第i个json对象即JSONObject
        		//data[i]通过.字段名称即可获得指定字段的值
        		console.log(json[i].userName);
			}

相关链接:点击打开链接点击打开链接

应用5:对一个内置对象进行一个功能上的扩展(原型属性)

需求:数组本身没有排序的功能,给其内置一个函数,进行功能性的扩展

1、书写一个MyArray.js的文件

Array.prototype.getMax = function() {
	var max = this[0];//谁调用this就是谁
	for(var i = 1; i < arr.length; i++) {
		if(this[i] > max) {
			max = this[i];
		}
	}
	return max;
}

2、调用函数

<script src="js/MyArray.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			var arr=[10,60,80,90,100];
			var max=arr.getMax();//调用扩展的功能
			alert(max);
			arr.reverse();
			alert(arr);
</script>

注意:扩展方式的书写(两种)

五、延伸

继承链和类加载器的联系、sublime

JS的异步调用比Java的注册监听器好多

原生JS

JS的调试,通过控制台(Google--检查--Console)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值