《JavaScript高等程序设计(第3版)》教程纲要

词条

《JavaScript高等顺序设计》是2006年人民邮电出书社出书的图书,作者是(美)(Nicholas C.Zakas)扎卡斯。本书合适有肯定编程履历的开发人员浏览,也可作为高校相干专业课程的课本。

献给搬砖人士,求职人士很不错的基础踏实笔记

前四章

js诞生于1995年当时它的重要目的是处置惩罚考证操纵现在生长成为一门壮大的编程言语,由三部份组成:中心(ECMAScript)DOM文档对象模子、 BOM浏览器对象模子

js 安排在 页面的合理位置 关于优化加载有很大的协助

牢记安稳退步,假如不支撑的状况下 有很多种计划 ,书中提到了

<noscript>  元素  </noscript>

当页面支撑剧本,用户永久也看不到它,只管他是页面的一部份。

语句末端加上分号,在某些状况下会增长代码的机能,由于解析器没必要花时候推想应该在那里插进去分号了。

一、数据范例

关于 undefined范例,在运用var声明变量但未对其加以初始化这个变量的值就是undefined,包含undefined值的变量与还没有定义的变量还不一样。

var message;

alert(message) // undefined
alert(age) // 发作毛病

关于 NAN

即非数值,不是一个数字。

NAN与任何值都不相称,包含它本身

alert(isNAN(NAN))  //是不是 不是一个数字  true
alert(isNAN(10)) // false
alert(isNAN('ni')) // true
alert(isNAN(true)) // false 由于true 可以被转换为1
typeof() 用来检测给定变量的数据范例
1.undefined  声明变量没有定义
2. null 空对象指针 
3. bloolean 
4. number  数值转换 Number()函数在转换字符串时比较复杂而且不够合理,引荐运用,parseInt()parseFloat()
5. string 字符串范例  toString() 有个瑕玷 对null 和 undefined 不起作用
6. string() 要领更周全
7. object 对象

二、语句

do-whlie语句 是一种后测试轮回语句,换句话说代码最少实行一次

do{
    i+=2;
}whlie(i<10)

whlie语句属于前测试轮回语句,相对for语句也是

var i = 0
whlie(i<10){
    i+=2
}

关于break和continue语句

var num = 0;
for(var i = 0;i++;i<num.length){
    if(i%5==0){
        break;
    }
    num++;
}

alert(num) //4  break 是马上退出轮回强迫实行轮回背面的语句


var num = 0;
for(var i = 0;i++;i<num.length){
    if(i%5==0){
        continue;
    }
    num++;
}

alert(num) //8  continue 退出轮回后从轮回顶部继续实行
  1. for in 语句 用来罗列对象属性 注重一点 : 输出的属性名 递次不可展望。
  2. 明白参数 : 经由历程 arguments 对象的length 可以获知有多少个参数 通报给了函数。

函数体内可以经由历程arguments 对象来接见这个参数数组 类数组
经由历程arguments[0]接见第一个参数,arguments[1]接见第二个参数
函数没有重载,定义两个雷同名字的函数,后一个会掩盖前一个 经由历程搜检传入函数中参数的范例和数目做出差别的回响反映,来模拟要领重载,以下所示。

function add(){
    if(arguments.length ==1){
        alert(arguments[0]+10)
    }else if(arguments.length ==2){
        alert(arguments[0]+arguments[1])
    }
}

add(10) //20
add(10,20) //30

js 变量包含两种数据范例 其一 基础数据范例 其二 援用数据范例

三、基础数据范例与援用范例

基础数据范例指的是简朴的数据段,援用范例保留在内存对象中不能直接操纵对象的内存空间,操纵对象是现实上操纵的是对象的援用。

var num1 = 5
var num2 = num1

num2与num1是完整的自力的,两个变量互不影响,是副本的关联
var obj = new object ;
var obj2 = obj;

obj.name = 'nihao';
alert obj2.name    结果是 nihao

差别的是 这个值的副本现实是 指向了同一个对象 当obj 增加了name属性后 可以经由历程 obj2 来接见

函数的参数 现实上是其函数的部分变量

每一个函数都有本身的实行环境,现代实行的时刻会建立一个作用域链,对环境的一切变量做有序的接见

查询标示符 也就是 搜刮 历程 假如部分环境找到了该标识符 则搜刮历程住手 不然 一向追溯到全局环境的变量

作用域链 引发了闭包的观点 全局变量只能接见全局的环境 而部分环境不仅可以接见本身 还可以接见其 父级

js 是一门具有渣滓 网络机制的编程言语 没必要体贴内存题目 标记消灭是现在主流的 渣滓网络算法给当前不运用的值加上标记然后再接纳其内存 援用计数 现在不再运用的算法,消弭援用对渣滓接纳机制有优点是很好的机能优化计划

第五章 援用范例

  1. 怎样运用对象
  2. 建立并操纵数组
  3. 明白js的基础数据范例

援用范例,有时刻也称为对象定义由于他们形貌的是一类对象所具有的属性和要领。

一、object范例

建立object实例的要领:

  1. new操纵符背面加上object组织函数
  2. 字面量示意法
var per = {
    name: '',
    age: 23
}

思考题—基于typeof 检测属性是不是存在,运用字面量来指定差别的数据,做差别的显现

function show(arg){
    var output = '';
    if(typeof arg.name === 'string'){
        output += 'nihao' + arg.name;
    }
    if(typeof arg.age === 'number'){
        output+= 'Age:'+ arg.age
    }
    alert(output);
}
show({
    name:'lish',
    age: 23
})

show({
    name:'zbg'
})

二、array范例

与其他言语的辨别: 都同为数据的有序列表,然则js的数组每项可以保留任何范例的数据

建立体式格局 同object范例

数组的length属性 不是只读的,可以修改!

数组检测 有两个题目:instanceof、array.isArray(),假如有多个框架会有多个全局实行环境会存在差别版本的组织函数,后者目的是肯定这个值是不是是数组,不论是在谁人环境建立的

转换要领: 一切对象都具有toLocaleString、toString、valueOf ,前者与后二者差别的是为了取每一项的值挪用的是每一项的toLocaleString,而不是toString。
末了运用join()重现了toString的要领,通报逗号将以逗号支解,通报双竖线将以双竖线支解

ecmascript特地为数组供应了push和pop要领,模拟栈要领,后进先出。
unshift和shift先进先出。

重排序要领:sort()

function com (val1,val2){
    if(val1<val2){
        return -1;
    }else if(val2>val2){
        return 1;
    }else{
        return 0
    }
}
var arr = [12,2,3,34,567];
arr.sort(com)
alert (arr);

操纵要领: concat() 不转变原数组,复制原数组返回副本,会被增加到原数组的末端

var arr1 = [1,23,3];
var arr2 = arr1.concat("one",[8,"two"])
arr2 => 1,23,3,one,8,two

slice()用于截取数组,不转变原数组建立一个新数组

arr.slice(1) 从下标1最先到完毕
arr.slice(1,4)同理
假如是负数,用数组的长度做运算,再假如完毕位置小于肇端位置返回空数组

splice() 用于删除、插进去、替换数组

arr.splice(0,1) 从第零个最先删除1位
arr.splice(1,0,"one") 从第一个位置最先不删除 插进去一项
arr.splice(1,1,"two") 从第一个位置删除一名 插进去一项

filter() 用于数组挑选

var bg = arr.filter(function(item,index,array){
    return (item>2)
})
console.log(bg)

map()要领 和foreach() 类似

var bg = arr.map(function(item,index,array){
    return (item+2)
})
console.log(bg)

合并要领 reduce()和reduceRight()

运用合并要领求数组之和

var val = [1,2,3,4,5]
var sum = val.reduce(function(pre,cur,index,array){
    return pre+cur
})
alert(sum) 15

pre代表前一项 cur代表当前项  
reduce 和 reduceRight 结果雷同但取决于从哪头最先遍历数组。

三、date范例

经常使用的时候戳

`var start = +new Date()

dosomething();

var end = +new Date()

result = end-start`

四、regExp范例

婚配第一个 bat 或许 cat 不辨别大小写

var pattern = /[bc]at/i;

婚配第一个[bc]at 不辨别大小写

var pattren = /\[bc]\at/i;

婚配一切以 at末端的字符不辨别大小写

var partten = /.at/gi;

婚配一切以 .at 末端的字符不辨别大小写

var partten = /\.at\/gi;

test()要领

var text = "000-00-0000";
var partten = /\d{3}-\d{2}-\d{4}/;
if(partten.test(text)){
    alert('yes')
}

五、function范例

函数没有重载

var add  = function(){
    return num+100
}
add  = function(){
    return num+100
}
var result = add(200)  //300

在建立第二个函数时,现实上掩盖了第一个函数的变量

函数声明与函数表达式 声明提早

函数声明由于在代码实行之前,引擎会声明函数并将他们放到源代码树的顶部,
而关于表达式:

alert(sum(10,10));
var sum = function(){
    return num+num2
}

在实行到语句之前,变量sum中不会保留对函数的援用

作为值的函数

设想依据某个对象属性对数组举行排序

function newsort(pro){
    return function(obj1,obj2){
        var val1 = obj1[pro];
        var val2 = obj2[pro];
        if(val1<val2){
            return -1;
        }else if(val1>val2){
            return 1
        }else{
            return 0
        }
    }
}

var data = [{name:'lj', age:23},{name:'db', age:45}];
data.sort(newsort(name)) //按姓名排
data.sort(newsort(age)) //按岁数排

函数内部属性

函数内部有两个特别的对象:arguments this,arguments重要保留函数的参数它还有一个属性callee 是个指针 指向具有arguments对象的函数

比方异常典范的阶乘函数

function fact(num){
    if(num<=1){
        return 1
    }
    else{
        return num* fact(num-1)
    }
}

为了消弭函数实行与函数名的耦合征象可以运用arguments.callee(num-1)
替换 fact(num-1)

在消弭了耦合状况以后 newfact可以一般盘算,但fact 只能返回0
var newfact = fact;
fact = fuction(){
    return 0
}
newfact(5) // 120
fact(5) //0

函数的属性和要领:

每一个函数都包含两个属性:length prototype 前者是吸收参数的个数,后者是保留
一切实例要领的真正地点。
每一个函数也都包含两个非继续而来的要领 apply()、call(),用以转变this的指向

function sum (num1, num2){
    return num1+num2
}

function callsum(num1, num2){
    return sum.apply(this, arguments)
}

alert(callsum(10,10))  //20

基础数据范例,运用new操纵符建立援用范例的实例,实行脱离作用域之前一向保留在内存中,而基础数据范例,只存在代码实行的霎时然后马上被烧毁

一、布尔,数字,字符串

截取给定位置的谁人字符 charAt 只接收一个参数

var str = 'nihao';
alert(str.charAt(1)) //i

字符串的拼接 concat 或许 + 加号操纵符

var str = 'nihao';
var newstr = str.concat('world', '!');

alert(newstr) // nihao world !

字符串的截取 slice()、substr()、substring()。吸收最多两个参数

  • 一个参数的状况:正数就不说了,关于负数末了者都邑转换为0 前二者结果雷同
  • 两个参数的状况:slice就不说了,substr会将第二个负数转换为0,substring也是将第二个负数转换为0,然则他会自动排序将小的位数放到前面 由(3,0)到(0,3),然则substr不会所以末了返回一个空字符串。

字符串的查找 indexOf match

var str = 'lele nihao,zheli shi di yi jia zhu';
var arr = [];
var op = str.indexOf('e');

while(op>-1){
    arr.push(op);
    op = str.indexOf('e', op+1);
}
//进入轮回后每次给indexOf通报上一次的位置加1
alert(arr)

trim() 会建立一个字符串的副本,删除前置及后置的一切空格

match()要领只接收一个参数 
var text = 'bat cat';
var parrent = /.at/gi;

var new = text.match(parrent)

字符串的替换 replace()

var text = 'bat cat';
var result = text.replace(/at/gi, 'oo')

字符串转数组的要领 split()

var text = 'arr,op,kj,hg,';
var result = text.split(',')
接收第二个参数,牢固数组的length

二、URL编码要领

encodeURL() 是对全部URL举行编码,
encodeURLComponent()对附加在现有URL背面的运用

三、 Math 对象

猎取数组中最大值和最小值 防止过量的运用轮回和在if语句中肯定数值。

var val = [1,2,3,4,5,6,7,8,9];

var max = Math.max.apply(Math, val);

这个技能的症结,把MAth作为apply的第一个参数,从而准确的设置了this、

`Math.ceil() 向上取整

Math.floor() 向下取整

Math.round() 四舍五入取整`

random()要领

值 = Math.floor ( Math.round() * 可以值的总数 + 第一个可以的值 )

function round(low, up){
    var sum = up-low+1 //总数
    return Math.floor ( Math.round() *sum + low )
}

var color = ['red', 'blue', 'green', 'yellow'];
var arr = color[round(0, color.length-1)]

console.log(arr)  //多是数组中包含恣意一个字符串

总结:第五章结束,在一切代码实行之前 作用域就已存在两个内置对象 global和math

第六章 面向对象

  • 明白对象属性
  • 明白并建立对象
  • 明白继续

面向对象有类的观点,经由历程类可以建立恣意多个雷同属性和要领的对象。

一、建立对象

1、工场形式,处理了建立多个类似对象的题目,却没有处理对象辨认题目
2、组织函数,本身也是函数只不过可以用来建立对象,瑕玷每一个要领都要在每一个实例上从新建立一遍,因而把函数定义转到组织函数表面,然则假如对象定义多个要领就要定义多个全局函数,终究致使没有封装性。

function Person (name){
    this.name = name,
    this.sayName = function(){
        alert(this.name)
    }
}

//注重函数名大写,是为了辨别其他函数
//再一次提到this重定向

var o = new object();
person.call(o,"li",25,"ha");
o.sayname() //li

3、原型形式,每一个函数都有一个prototype属性,她是一个指针,指向一个对象,实例同享。

function Person (name){
    Person.prototype.name = name,
    Person.prototype.sayName = function(){
        alert(this.name)
    }
}
var preson1 = new Person;
var preson2 = new Person;
alert(person1.sayname === person2.sayname) //true

虽然经由历程对象实例可以接见保留在原型中的值,但却不能经由历程对象实例重写原型中的值,假如同名该属性就会屏障原型中的谁人属性

function Person (){
    Person.prototype.name = 'lisj',
    Person.prototype.sayName = function(){
        alert(this.name)
    }
}
var preson1 = new Person;
var preson2 = new Person;
preson1.name = 'matou'
alert(person1.name) //'matou'
alert(person2.name) //'lisj'

运用hasOwnProperty 检测一个属性是不是存在于实例中
alert(person1.hasOwnProperty('name')) //true
alert(person2.hasOwnProperty('name')) //false

4、组合运用组织函数形式和原型形式

组织函数形式用于定义实例属性,而原型形式用于定义要领和同享属性

function Person (name){
    this.name = name;
    this.friends = ['ls','df']
}
Person.prototype = {
    constructor: person,
    sayname: function(){
        alert(this.name)
    }
}

var preson1 = new Person;
var preson2 = new Person;

person1.friends.push('Van')
alert(person1.friends === person2.friends) //false
alert(person1.sayname === person2.sayname) //true

二、原型链完成继续,经由历程将一个范例的实例赋值给另一个组织函数的原型完成

第七章函数表达式

定义函数的体式格局经常使用有两种:1、函数声明。2、函数表达式

函数声明

function show(){}

函数表达式

var say = fuction(){}

函数声明提早

关于函数声明,实行代码前会先读取函数声明,这就意味着前后都可以挪用。

而关于函数表达式 提早挪用就会报错,运用前必需声明。

函数表达式与函数声明的辨别

if(true){
    function say(){alert(1)}
}
else{
    function say(){alert(2)}
}

注:表面上看很合理,现实上是在js中属于无效语法,但引擎会尝试修改此毛病。

下面的这类写法就很好的处理了这类题目

var say;

if(true){
     say = function(){alert(1)}
}
else{
    say = function(){alert(2)}
}

二、递归

递归函数是在一个函数经由历程名字挪用本身的状况下组成的

function face(num){
    if(num<=1){
        return 1;
    }
    else{
        return num* arguments.callee(num-1)
    }
}

arguments.callee 是一个指向正在实行的函数指针,用它来完成对函数的递归挪用

也可以经由历程定名函数表达式来杀青雷同的结果

var face = (function f(num){
    if(num<=1){
        return 1;
    }
    else{
        return num* f(num-1)
    }
})

三、闭包

有权接见另一个函数作用域中的变量的函数

关于闭包与变量,即闭包只能获得包含函数中任何变量的末了一个值,闭包保留的是全部变量对象而不是某个特别的变量。

function nc(){
    var result = new Array();
    for(var i = 0;i< 10;i++){
        result[i] = function(){
            return i
        }
    }
    return result
}

可以经由历程一个匿名函数强迫让闭包的行动相符预期

function nc(){
    var result = new Array();
    for(var i = 0;i< 10;i++){
        result[i] = function(num){
            return function(){
                return num
            }
        }(i)
    }
    return result
}

关于闭包中运用this

var name = 'window'
var obj = {
    name:'lsj',
    say:function(){
        return function(){
            return this.name
        }
    }
}

alert(obj.say()()) //window
var name = 'window'
var obj = {
    name:'lsj',
    say:function(){
        var that = this;
        return function(){
            return that.name
        }
    }
}

alert(obj.say()()) //lsj

经由历程私有作用域模拟块级作用域

(function(){

})();

第八章 BOM

一、最好运用settimeout 去模拟 setinterval

var num = 0;
var max = 10;

function show(){
    num++;
    if(num<max){
        settiomeout(show, 500)
    }
    else{
        alert('done')
    }
}

settiomeout(show, 500)

二、location.search 查询字符串参数

function get(){
    var qs = (location.search.length>0? 
    location.search.substring(1):''),
    args = {},
    items = qs.length? qs.split('&'): [],
    item = =null,
    name = null,
    value = null;
    for(var i = 0;i++;i<items.length){
        item = item[i].split('=')
        name = decodeURLComponent(item[0])
        value= decodeURLComponent(item[1])
        if(name.length){
            args[name] = value
        }
    }
    return args
}

假定查询字符串为: ?q=javascript&num=0

var result = get()
alert(result['q']) //javascript

关于window途径跳转的几种要领:

location.assign('http://nihao.com')
location.href = 'http://nihao.com'
window.location = 'http://nihao.com'

//结果雷同

第十三章

  • 明白事宜流
  • 运用事宜处置惩罚顺序
  • 差别的事宜范例

事宜流形貌的是从页面中吸收事宜的递次。

IE的事宜流叫事宜冒泡:也就是点击事宜起首在div元素上发作,再向DOM树向上通报直到document对象

网景公司提出的事宜流叫事宜捕捉:document对象起首吸收事宜再从树往下传播到事宜的现实目的

<input type="button" value="yes" onclick="alert(event.type)" />

<input type="text" value="yes" onclick="alert(this.value)" />

经由历程一个函数处置惩罚多个事宜时,可以运用type属性

var btn = document.getElementById('de');
var handler = function(event){
    switch(event.type){
        case "click":
        alert(1);
        break;
        case "mouseover":
        alert(2);
        break;
    }
}

btn.onclick = handler
btn.onmouseover = handler

跨浏览器的事宜对象兼容

var EventUtil = {
    getEvent:function(event){
        return event? event: window.evnet
    },
    getTarget:function(event){
        return event.target || event.srcElement
    },
    perventDefault:function(event){
        if(event.perventDefault){
            event.perventDefault()
        }
        else{
            event.returnValue = false
        }
    },
}

var a = document.getElementById('link');

a.onclick = function(event){
    event = EventUtil.getEvent(event)
    EventUtil.perventDefault(event)
}


以上代码可以确保一切浏览器中点击该链接都邑阻挠默许跳转

事宜托付

建立在事宜冒泡机制上的事宜托付手艺
只需在dom树中最高层次增加一个事宜处置惩罚顺序,这类手艺占用内存少,dom援用少可以提拔团体的机能。

<ul id = 'list'>
    <li id="one">one</li>
    <li id="two">two</li>
    <li id="three">three</li>
</ul>

var list = document.getElementById('list');

list.onlick = function(){
    event = EventUtil.getEvent(event)
    var target = EventUtil.getTarget(event)
    switch(target.id){
        case "one":
        alert(1);
        break;
        case "two":
        alert(2);
        break;
    }
}
    原文作者:Lipa
    原文地址: https://segmentfault.com/a/1190000016138447
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞