JS基础篇

1、前引(**)
JavaScript由网景公司创造(也叫LiveScript)
学习JS的目标:为DOM和JQuery打基础
课程的内容:
JS语法基础(求异带同)——基本与C#的语法差不多
JS的DOM操作
我们所学的JS是嵌入到浏览器中的客户端JS,还有别的JS技术

2、基本用法(***)
->JS代码要放在一对<script>标签中 script的属性 type="text/javascript"
->或者通过外部导入
->现在使用的JS规范 EcmaScript v3 或 v5
->浏览器是从上往下执行的,解析也是从上往下执行的
3、类型与变量(****)
js中没有存在声明变量的类型一说,js是一门弱类型语言,全部的类型都用var来声明

->数据类型
—>基本数据类型
数字类型(number)、boolean类型和字符串类型(string)
->复合类型
对象(object)、函数(function)、数组(Array)、时间(Date)等
->空类型
null、undefined

ps:使用 typeof 变量 可以得到该变量类型的字符串

->声明变量:
单个声明:var 变量名 = 值;
批量声明:var 变量名 = 值
,变量名 = 值
,变量名 = 值
,变量名 = 值;
其中的值可以为任何类型
注意:在js中声明变量可以不是用var,没有用var声明的变量称为全局变量,具有全局性

->类型的转换
->数字转字符串
->第一种
数字 + "";
数字.toString();
String(数字);
->第二种(小数化方法 了解即可)
数字.toFixed(n) 指定输出小数点后n位数
数字.toExponential(n); //以指数的形式输出保留n位小数
数字.toPrecision(n); //保留有效数字n位
->字符串转数字
使用parseInt()、parseFloat()
使用Number()
使用数学式运算(加法除外——加法会连接两个字符串)
ps:alert(str-&#39;0&#39;);
alert(typeof (&#39;12&#39;*&#39;3&#39;)); //直接运算
->boolean转数字与字符串
使用Number()和String()
->数字转boolean
0为false 非数字true(非0数字:字符串)
NaN——false、Infinity——true
—>字符串转boolean
null或者为""时为false 其他为true
ps:Boolean常用的地方:进行浏览器的能力检测(兼容性)
将一个对象转换为Boolean类型最简单的方法就是参与Boolean运算
!! 运算符 alert(!!num); //num一开始为true 一次取反后为false 两个取反后回到原来的true
4、流程控制(与C#差不多)(**)
for-in与for循环一致
ps;for(var i in arr) {
alert(arr[i]);
}
5、运算符(与C#差不多)(**)
-> in 运算符
表示判断某个属性是否为一个对象的成分
<boolean> <string> in <object> ps;alert("sayHello" in p);返回true
-> instanceof 运算符
与c#中的 is 一样
<boolean> <object> instanceof<function> ps:alert(array instanceof Array);
-> 条件运算符 ? :
与C#一样
-> typeof运算符
第三点ps中
-> new与delete运算符
delete运算符可以删除属性
<boolean> delete 数据;
ps:var p = {a:"张三"};
var isTrue = delete p.a;
alert(isTrue);
6、数字类型(**)
js中所有的数字类型均为浮点类型
运算符与c#一致
特殊值
NaN(not a number)、Infinity(判断无穷)
Number.MAX_VALUE(数字的最大值)、Number.MIN_VALUE(数字的最小值)
Number.POSITIVE_INFINITY、Number.NEGATIVE_IFINITY
判断函数:
isNaN() 判断是否为非数字的函数
isFinite() 判断无穷

7、字符串(***)
常用属性:
length
string.length
substring的两个版本
一般截取的规则:左边取得到,右边取不到
stirng.sunstr(index, length); 从index开始截取取length位
substring(startIndex, endIndex); 从startIndex开始截取到endIndex
indexOf
<int> indexOf(string, startIndex) 从startIndex开始查找string字符的位置,也可以不加startIndex表示从头开始
split
<Array> split(&#39;要被分割的字符串&#39;, 取多少项);
其他参考W3School
8、基本数据类型的包装对象(***)
-> Number、String、Boolean
其实数值本身不具备方法和属性,但是js中做了包装处理,在调用方法是默认会在内部将数值类型转换为包装类型,
从而调用方法或属性。
-> 包装(wrapper)不仅具有和基本类型一样的值,还包含相关的方法与属性
-> 工作机制(瞬时创建、瞬时调用、瞬时释放)
一旦执行完临时建立的内存区域会立即被系统清理
-> 包装对象与原始类型根据需要自动互换
ps:Number类型在参与运算是会自动转换为number类型
9、 函数(*****)
->函数是一个可以执行的JavaScript代码片段
声明式函数:
function 函数名(参数){
函数体
}
使用:函数名(参数);

Lambda表达式(函数):
var 函数名(变量名) = function(参数){
函数体
};
使用:函数名(变量名)(参数);
ps:Lambda表达式其实就是更为简洁的匿名方法表达式(匿名方法:无函数名的函数)

->匿名函数的自调用与沙箱模式:
沙箱模式:定义自己的同时将自己调用,并且里面声明的变量不会对外面造成任何影响——JQuery本质就是一个沙箱
匿名函数可以实现自调用(js中的设计模式:沙箱模式)
注意: js中少用全局变量
在函数中声明的变量具有局部作用域
将函数括号起来,在函数的后面加上()表示自调用
这使得num变量只在函数中用到,而不用定义全局变量
例:将函数括起来把它当成函数名来调用 var 函数名 = function(){};
(function(msg){
var num = 10;
alert(num+&#39;,&#39;+msg);
})(&#39;今天天气好晴朗&#39;);
->Function对象
语法:Function 可以称之为动态数组
可以 以字符串的形式定义函数
var func = new Function(&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;alert(a+b+c);&#39;);——最后一个表示方法体前面的表示参数
相当于:
var func = function(a,b,c){
alert(a+b+c);
}
该对象在面向对象方面有非常强大的功能是所有函数类型的基类型

->arguments对象
每一个函数都有一个arguments属性(其长度根据参数个数)
arguments相当于数组存放着我们所输入的参数(如果函数没有定义参数,在js中也可以直接在调用是传参)
使用:arguments[index]
->arguments的callee属性
函数本身的引用(arguments.callee——函数自己)
在js中函数是以变量的形式声明的,随时都会有可能被从新赋值
而使用arguments.callee(表示函数最原始的状态) 就可以是函数

->函数的重载
函数并不能重载,只会被覆盖
->函数的预解释
函数中定义的变量不要放在函数中间,养成习惯
在函数一开始的时候就声明变量,再使用
原因:
js中所有函数在js代码被解释的时候,所有的函数都会预解释一次,
其中所有的的变量都会被移到函数开始的位置

函数名的提升
例:
var a = &#39;abc&#39;; //全局变量

var func = function(){//函数访问a
alert(a); //undefine
var a = 10;
alert(a); //10
}
func();
函数的预解释:
var func = function(){
var a;
alert(a);
a = 10;
alert(a);
}
->变量作用域(难点)
-> 全局作用域与局部作用域
全局作用域每个地方都可以用
局部作用域是函数定义的
->函数内局部变量优先级高于同名的全局变量
注意方法中变量要加var(如果函数中的的同名变量定义没有加var表示全局变量,修改值)
函数的解释期与执行期
ps:没有块级作用域(难)
-> 作用域链(难)
在js中每一个变量都是一个属性,要么属于全局对象,要么属于局部对象
->画作用域链
-> 整个script标签就是全局对象,作为第一条作用域链
在纸上画一条方框(或线也行),每一个全局的变量都是一个方框
-> 凡是看到函数,就表示一个新的作用域链
在原来作用域链的方框中分支出一条
-> 如此下来,凡是看到函数就新创建一个作用域链,
这个作用域链就是这个函数所在作用域的子作用域

->使用作用域链
当画出作用域链以后,就明确作用域的层次结构
在代码中js访问"属性"有一个规则
首先在当前作用域链上找,如果找到,直接拿来用
如果找不到,就去上一级作用域链中找,...
一直找到全局作用域链,还没找到就是TypeError

->函数闭包(难点)
-> 函数闭包的概念
闭包就是可以访问局部变量的全局函数
(变量的访问是通过作用域链从下至上的,而闭包就是通过上面的全局函数来访问下面的局部变量,逆了作用域链)
而这个访问局部变量的全局函数也是唯一一个可以访问它的函数
-> 如何定义函数闭包
例:var f; //在0级作用域链上定义变量
var func = function(){
//1级作用域链
var a = 10;
return function(){
//2级作用域链
alert(a);
}
}
f = func(); //将这个可以访问到局部变量的函数赋给0级的f,从而使的全局函数f可以访问1级的局部变量a
f(); //10
-> 闭包的常见应用
->用来定义具有私有成员的对象
例:
function PersonExt(name){//这里的传的name 就相当与在里面声明了一个变量name
this.get_name = function(){//get_name是方法
return name;
};//无法修改name的值
}
var pp = new PersonExt("里斯");
alert(pp.get_name());//里斯
//只能通过这一种方法来访问name了 pp.name访问不到
-> 函数轻量化(模块)
大大提高了代码执行的性能
例:
var func = (function(){
//这个用来匹配的正则表达式只会初始化一次,不会发生分开写然后初始化多次消耗性能
var o = {
">":">"
,"<":"<"
," ":""
};
//实际func是用了这个函数
return function(str){
var temp = str;
for(var i in o){//用循环来完成替换
temp = temp.replace(i, o[i]);
}
return temp;返回值
}
})();//实现函数自调用然后就是带参数的函数return给func
//自调用也可以带参数不过一般是实现函数的初始化
alert(func(">测 试<"))
-> 模拟面向对象
函数的闭包使得js的面向对象成为了可能

10、对象(****)
js中对象是已命名的数据的集合(即数值有名字,好似键值对)
->字面值(JSON)
->语法:var 对象名 = {
"名字1":值1 (任意类型包括函数、或者其他对象)
,"名字2":值2
,……
,"名字n":值n
};
说明:其中的双引号可加可不加,但是一旦名字中有空格的就要加了
->使用:使用的方法与C#一致(用对象名点出来)
->伪类
通过一个"函数",在函数中利用this为成员赋值,充当构造函数来模拟类
例:
function Person(){ //Person类 伪类
this.name = "赵健宇";
this.age = 18;
this.sex = "男";
//属性的名字(name,sex,age)不需要声明,直接用this.名字
this.SayHello = function(){
alert("你好,我是"+this.name+",今年"+this.age+"岁"
+",我是"+this.sex+"的");
};
}
//先new一个对象
var p = new Person();
//alert(p.name);
//调用方法
p.SayHello();
->new到底做了什么
// 创建对象是谁?new关键字
C#: function Person() {}
var p = new Person();构造函数的作用初始化字段
js:
new 在内存中创建对象,并返回一个对象的引用
Person() 调用构造函数,并将这个引用传入给该函数的this
在调用构造函数期间 使用 this.属性 = 值 不断的为这个对象添加成员
内存会自动的分配
var p = 将在新的对象的地址给p
ps:图(创建对象.bmp)
->可以为任意的对象添加任意的属性(键值对)——JS强大之处
可以在创建构造函数时添加任意的属性
也可以在创建对象后(new完)用(对象名.属性名 = "值")来添加属性——如果属性存在则覆盖掉,不存在则添加
->关联数组
在js中可以将对象当作数组用
object.pro 等价与 object["pro"]
例:
function Person() {
this.name = "赵建宇";
this.sayHello = function() {alert("你好");};
}
var p = new Person() ;

// alert(p.name);
// alert(p["name"]);

p["sayHello"]();
ps:关联数组还可以用以进行方法的扩张(prototype)

11、字面值的定义和数组的定义(****)
->字面值
定义:字面值就是直接写出来的值
例:var arr = [1,2,3,4,5,6]; //这就是一个字面值 同时也是一个数组的定义
arr既是object类型又是数组类型

->数组
常用的声明语法
var arr = [1,2,"赵建宇",true,&#39;杨洪波&#39;];可以直接将值(任意值)填入
ps:数组完整的声明方法(不是很常用)
var arr1 = new Array();
arr1[0] = "第一项";
arr1[1] = "第二项";
arr1[2] = "第三项";
注意:在插入语句时尽量用 数组名.length 来作为下标,防止插入的数据出现未赋值的情况
for-in的循环使用用来遍历数组下标的
js中是没有多维数组的如果需要则去构造一个var point = [[x1,y1],[x2,y2]];
数组的方法(重要)
sort 排序的
其他方法看w3cshool

12、null与undefined (***)
-> null是不指向,但是这个东西还是存在的
-> undefined表示没有,不存在
对象没有赋值的时候,要对它进行访问
声明了变量但是未赋值的时候
函数没有返回值,但是使用返回值代码(return)
-> null与undefined的比较
== 视两个相同然而实际并不相等,一般使用===和!==进行判断
=== 表示验证类型,并判断是否相同(在实际开发中判断类型等检查的时候多半使用三个等号,表示既要判断类型又要验证数据)
-> undefined不是js的保留字,是ecmascript的标准
写类库时可以在开始的时候使用代码var undefined; 保证其可用
-> 转换
转换为Boolean时两个时相同的都为false

13、其他对象(****)
->Date
获得当前时间
var d = new Date();
d Sun Aug 06 2017 13:03:17 GMT+0800 (中国标准时间)
d.toLocalString() 2017/8/6 下午1:04:32
d.toLocaleDateString() 2017/8/6——日期年份
d.toLocaleTimeString() 下午1:04:53——具体时间
ps: 实际开发中获得各部分时间不要用new Date().getXXX();
一开始得到一个时间,然后用这个时间进行其中各个部分的处理
获得部分时间
var currentDate = new Date();
currentDate.getYear(); 获得年份

其他的Date方法看http://www.w3school.com.cn/jsref/jsref_obj_date.asp
->RegExp(正则表达式——难点)
实际开发时对于字符串的处理,都是用正则表达式
匹配IsMatch、替换Replace、提取Match和Matches(C#中的方法,JS语法不同,功能相同)
在C#中正则表达式本质就是一个包含要匹配的字符和元字符的字符串

->元字符
基本:. 任意 () 优先级和分组 |逻辑或有最低优先级 []出现在括号中的的一个字符

限定:+ 一次到多次 * 0到多次 ?0或1次 {n}出现n次
{n,}出现至少n次 {n,m}出现n到m次

头尾: ^以什么开头 $以声明结尾

简写:\\\\d数字 \\\\D非…… \\\\w汉字、字母、下划线 \\\\W非…… \\\\s空格或换行符 \\\\S非空格或换行符
digital word space
->创建
字面值:var numRex = /^\\\\d+$/; 匹配数字
变量名 /正则表达式/——放在两个&#39;/&#39;之间
用构造方法创建(动态正则表达式)
var numRex2 = new RegExp("^\\\\\\\\d+$");//与上面的式子等同
->三个方法
->匹配(C#:IsMatch)
语法:
C#: boolean RegExp.IsMatch(字符串,"正则");
js: boolean 正则的对象.test(字符串);
例:
var str = "2fcsadfgds32434";
var res = numRex.test(str);
alert(res);
->提取单个、多个
->单个(C#:Match)
提取第一个得到的数据
语法:
C# Match Regexp.Match(字符串,正则)
js 类数组的对象 正则的对象.exec(字符串);
例:
var str = "d232fs3232";
var match = /\\\\d+/.exec(str);
alert(match[0]);//232 使用match[0]得到的匹配的结果(等价于C#中match.value)
常用的属性:
alert(match[0].index);
没有length 可以同match[0].length
没有Success,可以通过 match === null来表示
->多个(C#:Matches)
var n2 = /\\\\d+/g; 加个g表示全局模式匹配数字
var m1 = n2.exec(num);//此时匹配第1次,得到第一个结果
然后在进行提取第2次,等到第二个结果,以此类推,如果没有了数字得到null
ps:可以用过循环一次性获取
var m;
do{
m = n2.exec(num);
}while(m != null)
->替换(C#:Replace)
语法:
C# string Regex.Replace(旧的字符串, 正则表达式, 要匹配的字符串);
js string 字符串.replace(正则表达式, 要匹配的字符串);
例:
var d = "2013年9月26日, 2013年9月26日, 2013年9月26日";
var res = d.replace(/(\\\\d+)年(\\\\d+)月(\\\\d+)日/, "$1-$2-$3");
2013-9-26, 2013年9月26日, 2013年9月26日 没有在正则的后面加上g,所以只算第一个
var res = d.replace(/(\\\\d+)年(\\\\d+)月(\\\\d+)日/g, "$2/$3/$1"); 9/26/2013, 9/26/2013, 9/26/2013
->正则匹配组用法——获得文件路径(模拟Path的方法)
要注意C#中组从1开始,所以JS也是一样
在js中exec方法返回的对象[0]代表匹配到数据,匹配到的数据表示符合正则表达式的字符串
而从[1][2]等开始分成各个组
例:
var str = "C:\\\\\\\\1\\\\\\\\2\\\\\\\\3\\\\\\\\4.mp3"
var regex = /((.:).+\\\\\\\\)((.+)(\\\\..+))/;
//第一组表示:c:\\\\1\\\\2\\\\3\\\\
//第二组表示根目录:C:
//第三组表示文件名.后缀名:4.mp3
//第四组表示文件名无后缀名:4
//第五组表示.后缀名:.mp3
var res = regex.exec(str);
alert("匹配到的结果:" + res[0] + "\\\\r\\\\n"
+ "文件根目录:" + res[1] + "\\\\r\\\\n"
+ "文件夹路径:" + res[2] + "\\\\r\\\\n"
+ "文件名:" + res[3] + "\\\\r\\\\n"
+ "没有后缀名的文件名:" + res[4] + "\\\\r\\\\n"
+ "后缀名:" + res[5]);
-> Error
在C#中运行过程中的错误,成为异常
在js中异常就是一个对象 Error
-> try-catch的用法
例:var i = 10;
try{
i();//代码错误
//抛出异常,写下面这一句就表示由异常要抛出
//throw new Error("异常的消息代码");
alert("没有异常");
}catch(e){
alert(e);//会抛出异常显示,缺少函数
}finally{
alert("总是会执行的finally");
}
->XMLHttpRequest
专门用来向服务器动态的提交数据用的(因为还没有学ASP.NET所以暂时不学)
14、类型转换的注意事项与扩展(**)
->当声明的类型时包装类型(包装类型属于对象)时,Boolean值为true
var v2 = new Number(0);
alert(!!v2);//true
如果对象不为null就都为true
->数组转数字
数组参数为空时,转换为数字0
数组参数为1个时,转换为数字数组中的唯一项
数组参数为多个时,转换为数字为NaN

其余的看(类型装换总结.png)
15、逻辑或运算符 || (***)
->逻辑中断:
当求逻辑或时,前面一个为true时,后面的表达式可以不用计算
当求逻辑与时,前面一个为false时,后面的表达式可以不用计算
->解决浏览器的兼容问题
浏览器中的事件与C#中的事件是一样的,用户操作鼠标就会触发对应的事件
事件参数e,不同的浏览器有着不同的解释
IE浏览器使用的是window.event获得
火狐浏览器使用事件方法的参数e获得
使用逻辑或 || 使之浏览器的兼容问题得以解决
e = window.event || e;
16、四种调用模式——使用函数的四种方法(****难点)
-> 只要搞清楚两件事:
在不同的调用模式中this分别是什么?
用作是什么?
-> 函数调用模式
->this是什么:this表示全局对象
->作用:
一般完成特定的功能,使用this较少
只有在类库中局部处理数据才会用到
例:var func1 = function(){
alert("函数调用");
};
func1();
-> 方法调用模式
同样是函数,作为对象的属性值的时候,就叫做方法
方法:可以通过属性点出来的就是方法,方法必有一个他的对象
->this是什么:this表示当前对象
->作用:
一般方法是一个对象具有的功能(多用)
例:var o = {
name:"里斯"
,sayHello: function(){
alert(this.name);
}
};
o.sayHello();
-> 构造器调用模式(构造函数)
->this是什么:this表示当前对象
->作用:
作为对象的构造函数来调用,使用new来创建
例:function Person(){
this.name = "赵健宇";
this.say = function(){
alert(this.name);
};
};
ps:在构造函数调用模式下,return意义被改写
如果返回的是对象,那么起作用,原来的this.name对象被替换
如果返回的不是对象则无效
例:
function Person(){
this.name = "赵健宇";
this.sex = "男";
this.age = 19;

//返回的是对象,那么起作用,原来的this.name对象被替换
//返回的不是对象则无效
return {
name : "里斯"
};
}
var p = new Person();
alert(p.name);
//如果返回的是对象,则打印里斯 而其他属性为其它为undefined,因为新的对象中就只有一个name属性了
-> apply与call调用模式
每个函数都是一个对象
函数具有两种方法:apply和call
函数名.apply(对象, [参数数组]);
函数名.call(对象, 参数列表);
在调用的时候,第一个参数如果传参为null,即为函数调用模式
如果传一个对象,即为方法调用模式
例:
var num = 10;
function Person(){
alert(this.num);
}
//apply
//Person.apply(null);//10 //在调用的时候,第一个参数如果传参为null,即为函数调用模式
//Person.apply({num:"全局变量"}); //全局变量 //如果传一个对象,即为方法调用模式

//call与apply一样
Person.call(null); //10
//Person.call({num:"全局变量"});//全局变量
->通过apply来实现继承
例:
function Person(){
this.name = "赵健宇";
this.sex = "男";
this.age = 19;
};

var o = {
hobby : "打豆豆"
,sayHello : function(){
if(this.name){
alert("我叫"+this.name);
}else{
alert("不会说话");
}
}
};
//不继承时o.sayHello();输出不会说话
//继承
Person.apply(o);
//通过传一个对象使得,调用模式变成为方法调用模式,即this指向当前的对象,使得o中的this.name有值
//alert(o.hobby);
o.sayHello();
17、常用的函数(**)
-> encodeURI(编码唯一标识符)、 decodeURI(解码唯一标识符)
例:
var str = "杨洪波";
var res = encodeURI(str);
alert(res); //%E6%9D%A8%E6%B4%AA%E6%B3%A2
转换回来
var s = decodeURI(res);
alert(s);
ps:还有一个旧版本的转码 escape和unescape
例:
var str = "杨洪波";
var res = escape(str);
alert(res);//%u6768%u6D2A%u6CE2
-> parseInt、 parseFloat
var num = parseInt("123")
parseInt的注意事项
var num = parseInt("08");//最好不要写成这种格式、以前的浏览器会以为它是表示八进制所以结果为0
-> (*了解)eval
eval(string)
将字符串当做一个js代码来执行
例:
var s = "alert(&#39;123&#39;);";
eval(s); // new Function(); // EcmaScript5中推荐使用Function而非eval
具体原因看JavaScript权威指南
ps:在ajax中eval用的很多
在ajax中将由服务器传过来的json对象的字符串,变成一个对象
var res = "{name:&#39;赵建宇&#39;, say:function() {alert(this.name);}}";
res = eval("(" + res + ")");//将res字符串转换成为一个对象,固定格式
res.say();

猜你喜欢

转载自www.cnblogs.com/jingSpirit/p/9174320.html
今日推荐