第一章 javaScript 基础
推荐书籍:《javaScript高级程序设计(第三版)》、《JavaScript权威指南(第六版)》、《JavaScript面向对象编程指南》
一、Javascript概念及历史
1、javaScript概念
javaScript 是一种基于对象并具有安全性的脚本语言(一般运行于客户端的),是一种解释性语言,他基于对象,且不允许访问本地硬盘,也不允许对网络文档进行修改和删除,只能通过浏览器实现信息浏览和动态交互而与操作环境无关,是一种跨平台且具有安全性的语言。
javaScript实现组成:核心(ECMAScript)、DOM、BOM
2、javaScript发展史
<1>95年网景(Netscape)这个公司推出LiveScript。在此之前,没有所谓的前端技术。所有的服务都需要由服务器端进行操作。当时的目的是同时在客户端和服务器端使用。
<2>由Netscape(网景)公司联合SUN公司完善LiveScript。此时,Netscape公司将LiveScript更名为JavaScript。目的是利用Java语言的流行。
<3>微软在推出IE3.0时,使用了JavaScript的克隆版本,Jscript。
<4>此时,JavaScript拥有多个版本:版本不统一的问题出现!
<5>97年JavaScript1.1由欧洲计算机制造商协会定义。此举,只为JavaScript语言定制统一的语言版本。该全新版本的推出,更名为ECMAScript。该版本由Netscape、Sun、微软共同定义。
<6>微软的IE浏览器产品的推广,间接推广了JavaScript。(JavaScript脚本语言已经成为浏览器的必要组建、JavaScript语言的版本问题越加突出)。
<7>JavaScritp语言的版本不统一问题至今仍未解决!
二、js引用方式
方式一:头部或其他位置:<script type="text/javascript" ></script>而对于有大量js的选择放在页面后面更好。虽然部分浏览器支持defer
方式二:引入外部文件:<script type="text/javascript" src="demo.js">这里嵌入的js代码会被忽略</script>
方式三:直接嵌入脚本:<input value="提交" type="button" οnclick="alert('1')" />
注意:页面是从上至下加载的,<script>标签中js所在位置显得至关重要,当页面还没有加载到DOM时,js去调用该DOM对象就会报undefined。可以使用window.onload 等页面加载完成后再去执行js代码。
//操作节点的时候,需要节点加载到了才能取得再操作
//函数不会自己直接执行,需要被调用后才会执行
三、js代码注释方式
方式一://注释单行
方式二:/**/注释多行
在html4.0中,提供了一个<noscript>标签,对于不支持javaScript的浏览器或者不执行的浏览器,显示该标签里面的内容.(也可屏蔽不需要的js代码)
四、javaScript变量
1、变量命名:区分大小写,驼峰命名,规则与java相似
2、变量类型:js不要求指定变量中包含的数据类型,就是被称为弱类型语言,使用变量简单的用var来定义。
3、js支持以下数据类型:
<1>基本类型(简单的数据段)
number 包括整数、浮点数以及NaN(非数值 NaN和任何值都不相等,包括自己:alert(NaN == NaN)-->false)
boolean undefined,null,"",0转换为逻辑值为false,其他均为 true
string 包括单引号/双引号中的字符串值
null 无值,但是一个对象,只有一个特殊值就是null
undefined 未定义(代表一切未知的事物)[两种:根本不存在或者声明了,但没有赋值],只有一个特殊值就是undefined。
(undefined == null真)
注:以上类型的值为原始值,原始值是不可更改的。原始值的比较是值的比较。除了以上的原始值外,js中的值都是对象。而对象值是可变的,对象比的是引用。
检测基本类型用typeof操作符实用,检测引用类型使用instanceof
<2>引用类型(可能引用多个值构成的对象)
object 包括各种对象类型、Array 、 日期对象Date 等。
注意:js是区分大小写的,数据类型都是小写。不要和js内置函数Number,String、Object、Function混淆了
null和undefined最大的区别在于:被赋予null的变量通常被认为是已经定义了的,只不过它不代表任何东西。未申明或者声明未赋值的都为undefined,而声明复制为空,var a=null >>>typeof(a)--->object。另外他们的区别还在运算上有区别。对于尚未声明的变量执行typeof操作返回undefined。
例如:
var n = 12; // 数字类型的数据
var n2 = 12.3; //数字类型的数据
var str = "abc"; // 字符串类型 var str ='abc';
var flag = true; //布尔类型 var flag = false;
var date = null; //声明一个空的引用
var un; //未定义
var num = 13; //typeof(num)---number
var num2 = new Number(13);
alert(num == num2); 返回true
alert(num2 instanceof Number); 返回true
注:对象中有一个非常重要的对象——全局对象
4、基本包装类:
ECMAScript提供了3个特殊的引用类型:Boolean、Number和String.当读取基本类型的时候会创建一个对应的基本包装类。引用类型和基本包装类型的主要区别就是对象的生命周期不同。基本包装类型,只存在与一行代码执行瞬间,执行完立即销毁。
例如:var s1 =“some text”; //typeof s1 -->string基本类型
var s2 = s1.substring(3); //基本类型是没有方法的,自动包装
s1.color=“red”; //自动包装,只存在与一行代码执行瞬间
alert(s1.color); //上一行执行完就销毁了,这里无法通过对象.访问属性
5、js中关键字和保留字
关键字:
break case catch continue debugger default delete do else
finally for function if in instanceof new return switch
this throw try typeof var void while with
保留字:
Abstract boolean byte char class const double enum
export extends final float goto implement import int
interface long nativepackage private protected public short static
super synchronized Throws transient volatile let yield
五、字符集和特殊字符
javaScript采用UTF-16编码的Unicode字符集。Js中每个字符都是用两个字节(16位)表示的。利于中西文字转换。
ASCII(7位编码字符集,只适用于英文)、ISO Latin-1(8位的字符集,适用于大部分的拉丁语系)
GBK、Unicode(都是16为字符集,支持部分汉语系)。
特殊字符转义:
\‘ 单引号 \“ 双引号 \\ 反斜杠 \n换行 \r 回车 \b 退格 \t水平制表符 ......等
六、运算
alert("12"+1); // +链接字符 -------结果121
alert("12"-1); // 做减法时,把字符串转成数字类型,计算 -----结果11
七、数组
方式一:Var a = []; a[0] = 1;
方式二:var a = [1,2,3,4];
八、with 和 for in
1、With的用法
with用于设置代码在特定对象中的作用域[扩展作用域链]。
语法:with(expression){属性/方法}在调用属性和方法时,首先会监测该方法是否是本地方法,如果不是,则会监测它是否是传入的对象的属性/方法,然后再输出。例如:
例如:
var qs = location.search.substring(1);
var hostName = location.hostname;
可以改写成:
With(location){ //可以延长作用域链,代码块中可以直接使用location属性或者方法
var qs =(省略location.)search.substring(1);
var hostName = hostname;
}
注:with语句是运行缓慢的代码块,多数情况下少用。
2、for in 的用法
可枚举的属性或方法,精准的迭代。in 操作符只要通过对象能访问到的属性都会返回true,包括原型中的可枚举属性或方法
例如:
var obj={name:"Mike",
age:22,
height:188,
xueli:"本科"}
for(var i in obj){
console.log(i); // name age height xueli
}
九、NaN(not a number)--非数值
在其他编程语言中,任何数值除0都会报错,但是在ECMAScript中,任何数值除0都会返回NaN。
NaN与任何值都不相等,包括NaN本身。为此ECMAScript中定义了isNaN()函数,判断是否是非数值,非数值返回true.
十、数值转换
Number()函数可以用于任何数据类型转换,但是转换字符串时较为复杂,转换 Number() --遇空串 Number(“”) --- 0
--非首字符遇非数值会不会被忽略Number("123abc") --NaN
parsseInt() --会忽略空格,遇空串 parsseInt(“”)---NaN
--首字符串遇非数值parseInt("a123") --NaN
--非首字符遇非数值会被忽略parseInt("123abc") --123
parseFloat()
十一、label语句
通常会结合continue或者break语句使用
例如:
var num = 0;
out:
for (var i=0;i<10;i++) {
for (var j=0;j<10;j++) {
if(i==5 && j==5){
break out; //跳出标志位
}
num++;}
}
console.log(num); //55
第二章 javaScript 对象
一、对象的创建与访问
什么是对象:对象是一个整体,对外提供一些操作。很多时候我们可以认识这个对象。但是,并不关注其内部的细节。面向对象是一种通用的思想,一切皆对象。
1、创建对象的方式
javaScript Object Notation(JSON)----javaScript对象表示方法(JSON是javascript对象最好的序列化形式,它比xml更简洁,更省空间)
方式一:对象初始化程序创建[或者说->对象字面量]:
<1>创建一个没有任何属性的对象:var o ={}; //与new Obiect()同
<2>创建一个对象并设置属性及初始值:
var person = {name:”Angel”,age: 18 ,married: false}
var person = {“name”:”Angel”,age: “18” ,married: false}
原则上:属性名也可以加上“”,但是建议不加。特殊情况需要比如:
多个单词或者特殊符号必须加。
<3>创建一个对象并设置属性和方法
Var speaker={text:”hello world”,say:function(){this.text}}
<4>创建一个复杂的对象:
Var company={
name: “Microsoft”,
product: “softwares”,
employees:[{name: ”Angel”,age: 26},{name: “Hanson”,age : 32}]
readme:function(){document.write(this.name+this.product}
}
方式二:使用构造函数
<1>var anObj = new MyFunction(); / var anObj = new MyFunction; 不用()也可以
这里的function MyFunction(){//这是一种自定义构造函数,这里写代码,我们经常看到把这种形式的称为构造函数,是因为这种定义方式,js引擎会自动为我们调用Function的构造函数,创建对象}
方式三:使用Object.create()方法
此方法包含两个参数,第一个表示这个对象的原型,第二个可选参数,用于对对象属性的进一步描述
<1>创建一个普通对象:var o1 = Object.create(Object.prototype)
这种与前面两种创建的效果一样
<2>var o2 = Object.create(null) //o2不继承任何属性和方法,没有原型甚
至不包括基础方法[toString()......]
<3>var o3 = Object.create({x:1,y:2} //o3继承了属性x和y
2、属性特性(类型):
注:内部才用的特性,放在[[]]中。
<1>数据属性:
[[configurable]]:表示能否修改属性特性,能否通过delete删除。默认为true
[[enumerable]]:表示是否可枚举,能否通过for in循环遍历。默认为true
[[writable]]:表示能否修改属性的值。默认为true
[[value]]:属性的数据值。读取时从这个位置读,写入的时候保存到这个位置
默认存储的是undefined。
例如:var person = { name : “Nicholas”};
这里name属性的描述符[[Configurable]]、[[Enumerable]]、[[writable]]默认都为true.而 [[Value]],为它的指定值Nicholas
修改属性默认的特性:使用ECMAScript5中的:
Object.defineProperty(对象,属性名称,描述符对象)方法
例如:
var person = {};
Object.defineProperty(person,"name",{
writable:false,
value:"Nicholas"
});
console.log(person.name); //Nicholas
person.name="Mike";
console.log(person.name);//Nicholas
<2>访问器属性:
[[configurable]]:表示能否修改属性特性,能否通过delete删除。默认为true
[[enumerable]]:表示是否可枚举,能否通过for in循环遍历。默认为true
[[get]]:读取属性时调用的函数。默认值为undefined
[[set]]:写入属性时调用的函数.默认值为undefined
例如:
var book ={ _year:2004,
edition:1};
//IE9+、Firefox4+、Safari5+、Opera12+ Chrome支持defineProperty
Object.defineProperty(book,"year",{
get:function(){return this._year;},
set:function(newValue){
if(newValue>2004){
this._year = newValue;
this.edition+=newValue - 2004;
}
}
});
book.year=2006;
console.log(book.edition); //3
//一个属性值的改变,会导致其他属性值跟着改变
<3>读取属性特性:Object.getOwnPropertyDescriptor(对象,"属性")
例如:
var person = {name:"Mike"};
var descriptor = Object.getOwnPropertyDescriptor(person,"name");
console.log(descriptor.value); //Mike;
console.log(descriptor.configurable) //true 直接定义默认值
//Object.defineProperty(...)如果使用这个定义的对象值中没写这些属性:
//configurable/enumerable/wriable默认都为false
3、访问对象属性的方式
在js中只有object和function有对象化的能力。对象既有属性也有方法:
例如:
函数:function person(){};/var person= function(){};
person.sex = “男”; person.age=18;
对象:var anobject ={};
anobject.aProperty = “”; anobject.aMethod = function(){};
访问方式:
<1>函数/对象都可以用 名称.属性/名称.方法();anobject.aProperty
<2>数组下标形式,即名称[“属性名”]/名称[“方法名”]anobject [“aMethod”]
这种方式的好处在于,如果遇到属性名比较特殊的如中间多了一个空格,就不能使用点方式访问了,但是可以用[]来访问。
4、删除对象delete
delete只能删除自有属性,不能删除继承属性(要删除继承属性必须从这个属性的原型对象上删除,但是会影响所有继承这个原型的对象)
<1>delete book.author;
<2>delete book[“main title”]
5、属性getter和setter
我们都知道对象属性由名字、值和一组特性构成。在ECMAScript5中,属性值可以开用一个或者两个方法替代。那就是setter个getter。由setter和getter定义的属性称为“存取器属性”,和数据属性不同,存取器属性如果同时具有getter和setter方法,那么它是一个读写属性,如果只有getter方法,那么是一个只读属性,如果只有setter方法那么,它是一个只写属性。读取只写属性总是返回undefined。
例如:
var serialnum = {
$n: 0, //$符号暗示这个属性是一个私有属性
get next(){return this.$n++},
set next(n){if(n >=this.$n) this.$n = n;else throw “序号值不能小于当前值”}
}
6、对象的三个属性
每一个对象都有与之相关的原型、类属性和可扩展性。
<1>原型属性 [后面详解]
<2>类属性 严格的说,js中并不存在类的概念(构造函数替代)。这里的类指的是对象的类型,“”-- String false -- Boolean 但是,自定义对象类属性是Object,自定义对象无法通过类属性来区分
<3>可扩展性 是否可以给对象添加新的属性
7、对象序列化
是指将对象的状态转换成为字符串,也可以将字符串还原为对象。ECMAScrpit提供了内置函数JSON.stringify()和JSON.parse()用来序列化和还原对象。
8、获取对象的属性。
<1>使用ECMAScript5中的Object.keys()方法:这个方法接收一个对象作为参数,返回一个包含所有的可枚举属性的字符串数组。
例如:
var test ={
name :"test",
age :24,
say : function(){
console.log("hello world");
}
}
var keys = Object.keys(test);
console.log(keys) //name,age,say
<2>使用Object.getOwnPropertyNames()方法:获取所有的实例属性,无论是否可枚举。可能这个对象上的属性中有不可枚举的使用Object.keys()无法全部知晓,但是这个方法包含了所有的属性。
9、查看对象的属性和值的方法总结:
<1>使用JSON将对象转为json字符串——JSON.stringify(对象)
<2>使用ECMAScript5中的Object.keys()方法,查看对象上可枚举的属性
<3>使用ECMAScript5中的Object.getOwnPropertyNames()查看所有的实例属性
<4>使用for in遍历对象的所有属性或方法(包括原型中的可枚举)
<5>其他,但是js中并没有提供直接返回对象属性个数的方法
var book = {
title:"js",
authors:["A","B"],
edition:3,
year:2011
}
//1、使用JSON方法,将对象转为json字符串,直接查看对象的属性和值
console.log(JSON.stringify(book));
//{"title":"js","authors":["A","B"],"edition":3,"year":2011}
//2、使用ECMAScript5中的Object.keys()方法,查看对象上可枚举的属性
console.log(Object.keys(book)); //title,authors,edition,year
//3、使用ECMAScript5中的Object.getOwnPropertyNames()查看对象上所有的实例属性
console.log(Object.getOwnPropertyNames(book));//title,authors,edition,year
//4、使用for in 遍历对象属性或方法(包括原型中的可枚举)
var stringBuffer = "";
for (str in book) {
stringBuffer += str+":\""+book[str]+"\",";
}
console.log(stringBuffer); //title:"js",authors:"A,B",edition:"3",year:"2011",
二、Js可以操作的对象
1、原生对象(本地对象)
原生对象:由ECMAScript实现提供的、独立于宿主环境的所有对象。与宿主无关(在IE、nodejs等均有这些对象),在ECMA-262中已经定义的类型。在运行过程中动态创建的对象,需要new。原生对象中有一种在ECMAScript引擎初始化阶段就被创建好的对象,不必实例化的对象,叫内置对象。
常见的原生对象:
<1>数据封装类:Object、Array、Function、Boolean、Number、String
<2>工具类:Date、RegExp
<3>错误类:Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError
具体如下:(因表格合并有bug,只传图片)
2、宿主对象
宿主对象并不是引擎的原生对象,是由宿主框架通过某种机制注册到JavaScript引擎中的。对嵌入到网页中的JS来说,其宿主对象就是浏览器提供的对象,不同的浏览器提供的宿主对象可能不同。在浏览器中,所有的BOM和DOM对象都是宿主对象。(window对象不是ECMAScript中的内置对象,浏览器会为html文档创建一个window对象,所以在全局作用域中申明的属性和方法,window对象都能访问到,自定义对象也是宿主对象,打印自定义对象会显示源码)
三、本地对象详解
1、Array对象
<1>Array对象的构造函数形式:
Var variable = new Array(); variable[20] = “test19”;
Var variable = new Array(20);
Var variable = new Array(arg1,arg2,....) / Var variable =[0,1,2,3,4]
<2>Array对象常用的方法
①push(数组元素) 在数组末端添加新元素--返回改变后的数组长度
例如:a = []; a.push(“zero”);a.push(“one”,“two”)
②pop()移除最后一个元素 --- 返回移除的元素
③shift() 移除数组中的第一项--返回移除的元素
④unshift() 在数组前端添加项 --返回改变后的数组长度
⑤sort() 数组排序-默认是小到大,也可以传参数(比较函数)从大到小
⑥reverse()将数组中的元素颠倒顺序
⑦concat()返回一个新的数组,但不会修改原始数组
例如:var a = [1,2,3]
a.concat(4,5)/a.concat([4,5]) //[1,2,3,4,5]
⑧slice()返回一个数组的片段或子数组
例如:var a = [1,2,3,4,5]
a.slice(0,3); //[1,2,3]
⑨splice() 主要功能:向数组中插入项。也可删除、替换
⑩join() 将数组中所有的元素转化为字符串并连接在一起,是split()的
反向操作,例如:
var a = [1,2,3];
a.join(); //“1,2,3”
a.jion(“ ”); // “1 2 3”
a.jion(“”); // “123”
<3>数组迭代方法
every():对数组中的每一项运行给定函数,如果对每一项都返回true,结果
返回true.
filter():对数组中的每一项运行给定函数,返回符合条件true的数组
forEach():这个方法没有返回值(ECMAScript5)
map():返回数组
some():every全为true则返回true.这个有true就返回true.
例如:
var number = [1,2,3,4,5,4,3,2,1];
var everyResult = number.every(function(item,index,arry)){
return (item >2)
} // false
var someResult = number.some(function(item,index,arry)){
return (item >2)
} // true
var filterResult = number.filter(function(item,index,arry)){
return (item >2)
} // [3,4,5,4,3]
number.forEach(function(item,index,arry)){//里面执行某些操作}
var mapResult = number.map(function(item,index,arry)){
return (item*2)
} // [2,,4,6,8,10,8,6,4,2]
2、Boolean对象 [基本包装类]
bool1 =new Boolean(0); //返回false,其他数字都为true
bool2 = new Boolean(null); //返回false
3、Date对象
创建日期对象的方法:
Var variable = new Date(); //得到系统时间,一堆,这对象可获取具体的
Var variable = new Date(milliseconds/毫秒);//从1970年1月1日凌晨算
Var variable = new Date(String);
Var variable = new Date(year,month,day,hours,minutes,seconds,milliseconds);
日期对象方法 | 说明 |
getTime() | 得到秒数,从1970年1月1日开始计算的秒数 |
getYear() | 得到年份? |
getFullYear() | 得到四位的年份 |
getMonth() | 月份0-11,所以正确的要+1 |
getDate() | 得到日 |
getDay() | 得到星期几 |
getHours() | 得到小时 |
getMinutes() | 得到分 |
getSeconds() | 得到秒 |
setTime(value) | setYear(value)、setMonth(value)......setSeconds(value)) |
toDateString() | 例如: Tue Oct 04 2016 |
toTimeString() | 例如: 12:37:55 GMT+0800(中国标准时间) |
toLocaleDateString() | 例如:2016年10月4日 |
toLocaleTimeString() | 例如:下午12:37:55 |
计算执行时间:var start = Date.now();
var stop = Date.now();
var result = stop - start;
另外有一个控制台计算时间的方法:
console.time(“名称”);
//代码执行
console.timeEnd(“名称”)
注:在控制台,中可以看到: 名称:执行时间 ms
4、Function 对象
var myfunction = new Function(“x”,”y”,”return x*y”); //可以将函数作为对象访问
不推荐上面的写法:
等效于:function myfunction(x,y){return x*y} //构造函数模式
注:所有的函数都是Function对象(类)的实例
5、Number 对象[基本包装类]
mynum = new Number(100); ----- mynum.valueof();
----- mynum.toString();
6、Object对象
Object对象时派生所有其他,其属性和方法可以派生给所有其他对象。
7、RegExp对象
进行模式匹配的正规表达式。
Var variable = new RegExp(pattern,flags)
8、String 对象[基本包装类]
Mystr = new String(“this is a String”)
mystr.toLowerCase();
mystr.toUpperCase();
常用字符串操作方法:
charAt(num) 返回指定索引位置字符
indexOf(String) 从前往后,返回String首次出现的位置
lastIndexOf(String) 从后向前,返回String首次出现的位置
split(separator) 分割
Substring(num1,num2)截取