当熟悉了Java语法,从 java角度去看Js,发现存在很多相似之处,比如 整体上看Js也是一种面向对象的语言,只不过 身为一种解释执行的语言,没有必要做的和Java那么复杂,因此 用了一些的很巧妙的简化
从面向对象的角度看Js
-
什么是面向对象
面向对象 的语言,只要的特点就是 继承 、 封装 、 多态。这里就不多说了。 -
Js视角看面向对象
上边简单说了一下,面向对象语言特点,接下来看看Js是如何实现面向对象的
封装 :
Js也可以封装一个对象, 用来将属性和方法封装到一个对象中 , 如下代码。var zhangSan = { name : 'zhangSan', age : 14, play :function(){ console.log("I can play"); } }
Js中只有对象,没有类,直接用对象将属性和方法封装
聚合 :
和Java中 对象组合一样, Js中也可以做到对象聚合, 讲一个对象作为另一个对象的属性var door ={ height : 20, color : 'red' } var home = { front : door, // 将门这个对象作为home的一个属性 back : 'stone' }
继承 :
Js也是有继承的,不过做的很特殊,之后会单开一篇详细介绍Js如何处理继承, 这里简单描述一下,Js继承主要有下边两种方式- 基于原型链
- 基于对象继承 :
js中 对象继承,可以视为对象A扩展对象B
多态:
存在继承,就一定会有多态, 子对象继承父对象 , 如果存在重写, 执行相同的方法,产生的结果不一定相同,这就是多态。
浅谈一下,编程语言中哈希表和关联数组
开发语言中, 哈希表和关联数组是组织数据的两种方式。
1. 一般数组,也叫索引数组(通常以数字为键名) ;
2. 关联数组,也叫哈希表(通常以字符串为键值)
在Js中一般数组用数组表示、关联数组用对象表示,接下来讲一下Js中对象
Js中对象是什么
-
对象的定义
对象是由 “表示对象变量名” + 大括号 + 属性键值对,如下代码.var obj = { name : 'aaa'}
上边用{}的方式 定义了一个对象, 这种表示方法叫做 “对象文本标识法”,相似,还存在一种用 [] 定义数组的方式 叫做“ 数组文本标识法”
var arr = [1,3]; var obj = {age:12}
-
对象的属性
Js中对象 的可以是 数字、字符串、数组 、对象等, 这一点和Java 相似,有点相似有点不一样的是Js中属性可以保存函数 。var per = {name:'人类'} var teacher = { spe : per.name, // 指向另一个对象的属性 speak : function (param) { alert('i am teacher') }, age : 30 }
获取对象中的属性,和Java类似,可以用 点操作符 ,Js中也可以用自己独特的方式 中括号
teacher.age; teacher['age'];
注意: 大部分情况下,上边两种方式都可以,但是有些情况下,只可以用中括号
比如 特殊属性名,不确定属性名 必须用[]var x = 'age'; teacher[x]; // x是一个变量表示的key,只可以用中括号获取属性
此外, Js中可以用点或者[] ,自由组合获取多层嵌套的对象。 这一点也和Java类似
var book = { name: 'Catch-22', published: 1961, author: { firstname: 'Joseph', lastname: 'Heller' } }; //想访问这本书的作者的姓氏 // 注意 :这里只是演示,好的习惯是做好非空判断 alert(book.author.firstname) alert(book.author['firstname'])
对象的方法也是 属性,也可以用上边的点或者中括号取值 , 然后用括号符调用方法
teacher.speak(); teacher['speak']();
-
修改对象属性
上边介绍了如何获取对象中属性,接下来,讲一下,JS中如何修改对象的属性 。
和Java类似,也是可以通过赋值的方式直接修改对象的属性,和Java略微不同,Js中一般不需要写get set方法,不需要考虑,变量可见性问题 -
动态添加对象属性
Java语言是编译执行的,因此无法在运行时对 对一个对象添加属性。 Js则可以给一个对象添加属性,而且非常简单,直接用赋值的方式即可var obj = {}; // 此时对象中是空的,没有属性 obj.newAttr = '123'; // 可以直接利用赋值的方式赋值,不会报错 obj.newAttr ; // 输出 '123'
-
动态删除对象属性
直接用delete即可删除// 动态删除属性 delete per.name alert(per.name)
对象中this值使用
- 和java一样, 处于某个对象的方法内部时,可以用 该对象的特殊值 this 访问对象的属性
var school = { name : '一中', speak : function (){ alert(this.name + '欢迎您') } }
构造器函数
Java类中会有构造函数,Js对象可以直接定义,依然也有构造函数,不一样的是,构造函数可以单独写,不需要写在类中,其他方面类似
1. 内部用this 赋值
2. 可以用new 调用函数 ,从而生成对象
function Hero(){
this.occupation = 'Ninjia'
}
var hero = new Hero();
alert(hero.occupation);
// 构造函数也可以传参
function Student(age){
this.age = age;
}
// 忘记使用new , js不会报错,但会出现出人意料的结果
var h = Hero('Leonardo');
console.log(typeof h) // undifined
console.log(occupation) //输出Leonardo (因为this引用全局对象)
- 构造函数不用new调用,出现问题原因就是
// 相当于调用普通方法,this指向window,全局对象
var h = Hero('Leonardo');
console.log(occupation) //输出 Leonardo
- 使用 new 来调用相同的构造器函数,我们就会创建一个新对象,并且 this
也会自动指向该对象
构造器属性
当我们创建对象时,实际上同时也赋予了该对象一种特殊的属性—即构造器属性( constructor property)
// 构造器属性 , 是对象的属性, 指向构造函数
function Hero(name){
this.name = name;
}
var h = new Hero('美队');
console.log(h.constructor)
//输出 function Hero(name){ this.name = name;}
- 通过一个对象能够得到构造器函数,所以可以创建对象
var h1 = new h.constructor('蝙蝠侠')
- 通过{}创建对象,本质上是由 javaScript内建构造器 Object() 函数索创建的
var o = {};
console.log(o.constructor)
// 输出 function Object(){native code}
instaceof 操作符
判断某对象是否由某个构造器函数创建
function Hero(){}
var h = new Hero();
var o = {};
// 不是函数调用,只用函数名即可
console.log( h instanceof Hero); //输出true
console.log( h instanceof Object); //输出true
console.log( o instanceof Object); //输出true
返回对象的函数
用new调用构造器函数, 也可以用一般函数返回对象
// 这只是 创建多个相似属性键值对 对象的一种快捷方式,产生的对象彼此并无关系
function factory(name) {
return {
name: name
};
}
var o = factory('one');
o.name;//输出 one
传递对象
当我们拷贝某个对象或者将它传递给某个函数时,往往传递的都是该对象的引用,我们在引用上所做的任何改动,实际上都会影响它所引用的原对象
var original = {howmany: 100};
var nullify = function(o) {o.howmany = 0;}
nullify(original);
console.log( original.howmany);
对象比较
var fido = {breed: 'dog'};
var benji = {breed: 'dog'}
console.log(benji === fido) // 输出false