JavaScript 学习笔记

来源:互联网 发布:淘宝买家信用怎么升级 编辑:程序博客网 时间:2024/06/05 11:04

JavaScript 包含三部分
1.ECMAScript 语言的核心 常用的是ECMA 3
2. 文档对象模型 DOM
3. 浏览器对象模型 BOM\

基本数据类型

数字字符串布尔值undefinednull

undefined 和 null 的区别是一个是未定义,一个是定义了但是没有值

非基本类型(即对象)

查看类型操作符 typeof

numberstringbooleanundefinedobjectfunction

number 类型的变量
如果以数字0开始,那代表着是八进制数。
如果以0x开始,那代表着是十六进制数。
2e+3 是指数表示法,代表2后面加3个0 ,即2000
Infinity 是一个特殊值,表示超越了JS处理的最大数
NaN 是一个数字,比如拿数字和字母相操作就会得到NaN,而且据有传染性。

任何数据转字符串类型
var a = “” + anyVar
typeof a
->String

特殊字符串
\ 代表 \
\’ 代表 ’
\” 代表 “

\n 换行符
\r 回车符
\t 制表符

\u Unicode码

逻辑运算符

&&
||

比较运算符
== 相等运算(两边的变量会自动转换为相同的类型后进行比较)
===严格相等运算,幕后不存在任何转换
!= 同上
!== 同上
>

=
<
<=

NaN==NaN 会返回false

数组
var a=[]
var a=[‘1’, ‘2’, ‘3’]
var a=[‘b’, ‘a’, 3] //可以是不同的数据的类型
数组里也可以套数组
a[0]=[1,2,3]
另外字符串也是数组
var a=”abc”
a[2] 的值为c

if 表达式
if(a>2) {
var result = a;
} else {
var result = b;
}

代码块
{
// 任意行代码
}

三目运算符
var a=1
var b=a==1?’1’:’2’
b
“1”

switch 语句
var a=1
var result=”

switch (a) {

case 1:     result="number1";    break; case 2:     result='number2 ';    break; default:    result="default";    break; 

}

变量的复制

数组及对象类型复制是引用传递

var a=[1,2,3]undefinedvar b=aundefinedb[1, 2, 3]b[0]=99b[9, 2, 3]a[9, 2, 3]

基本类型复制应该是值传递(只试验了数值类型和字符类型)

var a="abc"undefinedvar b=aundefinedb="def""def"b"def"a"abc"

循环
while

var i=0;while(i<10){i++;}

do while

var i=0;do{i++;}while(i<10)

for

for (var i=0;i<10;i++) {//any code}可以把循环体中的内容挪上去,如下for (var i=0;i<10;i++,//any code) {}死循环for(;;) { }

for-in

var a = [1,2,3];var result;for ( var tmp in a ){result = result + tmp; //此处的tmp是数组下标result = result + a[tmp]; //此处取的是相应的值}

函数
组成部分
function 函数名称 (参数1,参数2,参数3,) {

// 代码块return 语句

}
调用时
参数传少了会返回NaN
参数传多了,多的参数会被忽略

arguments 为内建变量,它能返回函数所接收的所有参数

function sum() {var i, res = 0,num = arguments.length;for (i = 0; i < num; i++) {res += arguments[i];}return res;}sum(1,2,3,4,5)15sum(1,2)3

预定义函数
parseInt()
parseFloat()
isNaN()
isFinite()
encodeURI()
decodeURI()
encodeURIComponent()
decodeURIComponent()
eval()

parseInt(param) // 默认为十进制 也就是radix=10
parseInt(param,radix)

parseInt("1000",2)8parseInt("1000",10)1000parseInt("1000",16)4096parseInt("1000",17)4913

encodeURI()

encodeURI("http://www.baidu.com?key=鲁")"http://www.baidu.com?key=%E9%B2%81"encodeURIComponent("http://www.baidu.com?key=鲁")"http%3A%2F%2Fwww.baidu.com%3Fkey%3D%E9%B2%81"

encodeURI() 用于编码整个URI,因为URI中的合法字符都不会被编码转换。
encodeURIComponent方法在编码单个URIComponent(指请求参 数)应当是最常用的,它可以讲参数中的中文、特殊字符进行转义,而不会影响整个URL。

eval() 会把其输入的字符串当做JS代码来执行 (比较危险)

eval('var ii=2');ii;2

这也就意味着,可以动态的执行未知的代码。

作用域

function f () { local=1; }undefinedlocalReferenceError: local is not definedf()undefinedlocal1

以上代码说明了,在变量名如果不加var会被当作全局变量的,在函数被加载过一次以后才可以访问。

函数也是数据

使用函数标识记法(function literal notation)

var f = function () { return 1; }f    function () { return 1; }f()    1typeof f"function"

函数与变量一样,命名规则为除数字开头以外的任何数据都可以(字母,数字,下划线,美元符号)

匿名函数

var f = function (a) { return a; }f(9)9

用法:

作为参数传递给其它函数执行某些一次性任务

函数回调
function add(a, b) {
return a() + b();
}

调用时可使用匿名函数
add (
function () { return 1; },
function () { return 2; },
);
执行结果为: 3

当我们将函数A传递给函数B,并且由B来执行A时,A就成了一个回调函数(callback functions)。
应用:

不做命名的情况下传递函数将一个函数的操作委托给另一个函数有助于提高性能

例:第一步使用第二步的值
本来要定义两个函数,现在定义一个。
function multi(a,b,c,callback) {
var i,ar=[];
for (int i=0;i<3;i++) {
ar[i]=callback(arguments[i] * 2);
}
}
下面是如何调用
multi(1,2,3, function(a) { return a+2 } )

即时函数
(
function() {
alert(‘boo’);
}
)();
定义 :函数定义之后马上执行

带参数的如下:
(
function(name) {
alert(name);
}
)(‘boo’);

另外一种写法:
(
function() {
alert(‘boo’);
}()
);

内部(私有)函数
其实就是函数里套函数(作用域跟函数一样)
function outer(param) {
function inner(theinput) {
return theinput * 2; //这里边的东西对外不可见
}
return inner(param)
}
函数返回函数
function a() {
alert(‘A!’)
return function() {
alert(‘B!’)
};
}
var test = a()
test()
B!

闭包
作用:可以利用闭包突破作用域链
e.g(1):
var a=’global’
var F=function(){
var b=’local’
var N=function () {var c=’inner’; return b;};
return N;
};
var inner = F();
inner();//此处调用时可以访问F里的局部变量
//输出:local

e.g(2):

var inner; var F=function () {
var b=’local’
var N=function() { return b };
inner=N;
};
undefined
F()
undefined
inner()
“local”

e.g(3):
function F() {
var arr = [],
i;
for (i = 0; i < 3; i++) {
arr[i] = function() {
return i;
}
}
return arr;
}
undefined
var arr=F()
undefined
arr0
3
arr1
3
// 事实证明返回来的只是一个函数结构体,具体执行时才去真正取相应的数值 ,那时候 i 已经执行完成,所以都是3

对象

一个简单的对象
var hero={
breed:’Turtle’,
occupation:’NinJia’
};
一个空对象
var hero={};
undefined
typeof hero
“object”

属性的访问方式:
hero.breed //第一种 适合知道明确的变量名
“Turtle”
hero[breed]
ReferenceError: breed is not defined
hero[‘breed’] //第二种适合动态的变量名,运行时才能确定 ‘breed’ 可以换成变量
“Turtle”

添加和删除属性
hero={}
Object {}
hero
Object {}
hero.a=1
1
hero.b=2
2
hero
Object {a: 1, b: 2}
delete hero.a
true
hero
Object {b: 2}

返回对象的函数

function fact(name) {
return {name:name};
}
var o = fact(‘one’);

构造器函数
function Hero() {
this.occupation=’NinJia’;
}
undefined
var hero=new Hero()
undefined
hero.occupation
“NinJia”
通过构造器的好处之一是它可以在创建对象时接收一些参数。一般构造器函数首字母都大写。

如果 var hero = Hero(); //没有new 关键字。那this.occupation将会变为全局变量。

通过构造器函数克隆对象

function Hero() {
this.occupation=’NinJia’;
}

var hero2=new hero.constructor();// new 关键字不可少
undefined
hero2
hero {occupation: “NinJia”}
hero.occupation=”Reporter”
“Reporter”
hero
hero {occupation: “Reporter”}
hero2
hero {occupation: “NinJia”}

对象比较时,比较的是地址 ,所以即使内容相同的对象==时也为false

控制台
console.log()/console.error()

Array 数组对象

var a=[]
a.length //长度
typeof a.length
undefined

var abc=[]
undefined
abc.length=6 //此处可以手动设置length
6
abc
[undefined × 6]
abc[0]==undefined //比较的时候,是没有引号的
true
abc[0]==”undefined”
false

eval 相同的作用(Function 内建构造器)
var sum=new Function(‘a’,’b’,’return a+b’);
undefined
sum(1,2)
3

函数也是对象(基类是Object,跟Java一样)
例如我创建了一个函数
function fun(a,b){return a+b;}
undefined
fun.toString //可以调用这个对象的基类方法toString 来返回这个方法的源码
“function fun(a,b){return a+b;}” //自定义方法的话,会返回全部代码

parseInt.toString()
“function parseInt() { [native code] }”//本地方法的话,会返回native code

call() 函数
作用:代码重用
var some = { name:’ninjia’, say:function(who){ return ‘hi,’+who+’,i am a’ + this.name; } }
undefined
some.say(‘kobe’)
“hi,kobe,i am aninjia”
var lu={name:’luxiaoshuai’};
undefined
some.say.call(lu,’kobe’) //此处使用call函数将新对象传入,say方法里的this将会指向新对象。
“hi,kobe,i am aluxiaoshuai”

apply() 函数
使用方法同call()函数一样,不同的是调用时传入的参数
some.say.apply(lu,[‘kobe’])
“hi,kobe,i am aluxiaoshuai”
如果有多个参数,[‘kobe’, ‘Jodan’, ‘Elfson’] 这样写即可

推断对象类型

Object.prototype.toString.call({})
“[object Object]”
Object.prototype.toString.call([])
“[object Array]”

number 的基本类型是 Number ,可以使用new 关键字来创建, typeof 为 object

转换某个数字为二进制时,可以使用
(8).toString(2) //十进制转2进制
“1000”
parseInt(‘1000’,2) //二进制转10进制
8

String 类型
内置方法
toUpperCase()
toLowerCase()
str.charAt(0)
str[0] 效果同上
indexOf
lastIndexOf

工具类
Math
Date

正则表达式
以下是两种写法
var re=new RegExp(“j.*t”);
var re=/j.*t/;
正则的属性:
g 默认为false,找到第一行就会停止
i 忽略大小写,默认为false
m 跨行搜索 ,默认为 false,不跨行
使用属性时:
var re=new RegExp(“j.*t”, “img”);
var re=/j.*t/img;

正则的方法
test() 返回匹配结果
exec() 返回匹配上的字符

/j.*t/.test(“JavaScript”)
false
/j.*t/i.test(“JavaScript”)
true

/j.*s/i.exec(“JavaScript”)
[“JavaS”]

match() 返回匹配对象
search() 返回所找到的第一个匹配的索引位置
“JavaScriptjerryshi”.match(/j/ig)
[“J”, “j”]

“JavaScriptjerryshi”.search(/j/ig)
0
“aJavaScriptjerryshi”.search(/j/ig)
1
“aavaScriptjerryshi”.search(/j/ig)
10

replace()
split()
“JavaScriptjerryshi”.replace(/j/ig,’z’) //将全部j替换成z
“zavaScriptzerryshi”
“JavaScriptjerryshi”.replace(/j/ig,”) //将全部j删除掉
“avaScripterryshi”

回调式替换
找到字符串时,如果还想进一步处理怎么办,不要着急,看下面就知道了。
“JavaScriptjerryshi”.replace(/j/ig,’z’) //将全部j替换成z,并且加上引号
如下:
function replaceC(match) { return “’”+match+”’” ;} // 定义一个函数用来处理
undefined

“JavaScriptjerryshi”.replace(/j/ig,replaceC) // 第二个参数传自定义的回调函数
“‘J’avaScript’j’erryshi”

‘one, two, three,for’.split(“,”)
[“one”, ” two”, ” three”, “for”]
‘one, two, three,for’.split(/\s*,\s*/)
[“one”, “two”, “three”, “for”]

异常处理

try {
notEx()
} catch (e) {
console.log(“error”)
} finally {
console.log(“alway run this”)
}
error VM1479:2
undefined
这种异常的处理方式跟Java很像了,不知道谁抄的谁的。

方法的length属性就是参数的个数
function abc(a,b,c){}
undefined
abc.length
3
function abc(a){}
undefined
abc.length
1

原型

prototype 是函数的属性

function normal(name,color) { this.name=name; this.color=color; }
undefined
normal.prototype={price:100,count:3} //定义原型
Object {price: 100, count: 3}
var a = new normal(‘lu’,’red’);//第一个对象
undefined
a.price
100
var a2 = new normal(‘tom’,’blue’);//第二个对象
undefined
a2.price
100
a.price = 50 //修改第一个对象的原型值
50
a2.price //第二个对象没有跟着变
100
normal.prototype.pri
undefined
normal.prototype.price=10 //修改原型的值
10
a2.price // 第二个对象变了,根原型保持一致(此时第二个对象没修改过这个值)
10
a.price // 第一个对象没变
50

a2.price=40//修改第一个对象的原型值
40
normal.prototype.price=12 //修改原型的值
12
a2.price// 第二个对象没变
40
a.price// 第一个对象没变
50

当所有对象的原型值没有发生过改变时,此时修改函数的原型值,所有通过构造器生成的对象都会跟着发生改变。
如果对象的原型值已经发生改变了,那么此时不会跟着函数的原型值改变而改变。

自身属性和原型属性重名时,自身属性优先。