摘要:词条高级程序设计是年人民邮电出版社出版的图书,作者是美扎卡斯。
词条
《JavaScript高级程序设计》是2006年人民邮电出版社出版的图书,作者是(美)(Nicholas C.Zakas)扎卡斯。本书适合有一定编程经验的开发人员阅读,也可作为高校相关专业课程的教材。
献给搬砖人士,求职人士很不错的基础扎实笔记
前四章js诞生于1995年当时它的主要目的是处理验证操作如今发展成为一门强大的编程语言,由三部分组成:核心(ECMAScript)DOM文档对象模型、 BOM浏览器对象模型
js 放置在 页面的合理位置 对于优化加载有很大的帮助
切记平稳退化,如果不支持的情况下 有很多种方案 ,书中提到了
当页面支持脚本,用户永远也看不到它,尽管他是页面的一部分。
语句结尾加上分号,在某些情况下会增进代码的性能,因为解析器不必花时间推测应该在哪里插入分号了。
一、数据类型
关于 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++;ifor in 语句 用来枚举对象属性 注意一点 : 输出的属性名 顺序不可预测。
理解参数 : 通过 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) //30js 变量包含两种数据类型 其一 基本数据类型 其二 引用数据类型
三、基本数据类型与引用类型
基本数据类型指的是简单的数据段,引用类型保存在内存对象中不能直接操作对象的内存空间,操作对象是实际上操作的是对象的引用。
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 是一门具有垃圾 收集机制的编程语言 不必关心内存问题 标记清除是目前主流的 垃圾收集算法给当前不使用的值加上标记然后再回收其内存 引用计数 目前不再使用的算法,解除引用对垃圾回收机制有好处是很好的性能优化方案
第五章 引用类型如何使用对象
创建并操作数组
理解js的基本数据类型
引用类型,有时候也称为对象定义因为他们描述的是一类对象所具有的属性和方法。
一、object类型
创建object实例的方法:
new操作符后面加上object构造函数
字面量表示法
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(val1val2){ 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,twoslice()用于截取数组,不改变原数组创建一个新数组
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(val1val2){ 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() //li3、原型模式,每个函数都有一个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")) //false4、组合使用构造函数模式和原型模式
构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性
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()()) //windowvar 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二、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关于window路径跳转的几种方法:
location.assign("http://nihao.com") location.href = "http://nihao.com" window.location = "http://nihao.com" //效果相同第十三章理解事件流
使用事件处理程序
不同的事件类型
事件流描述的是从页面中接收事件的顺序。
IE的事件流叫事件冒泡:也就是点击事件首先在div元素上发生,再向DOM树向上传递直到document对象
网景公司提出的事件流叫事件捕获:document对象首先接收事件再从树往下传播到事件的实际目标
通过一个函数处理多个事件时,可以使用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引用少能够提升整体的性能。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; } }
- one
- two
- three
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/97012.html
摘要:然而,虽然先生对无所不知,被誉为世界的爱因斯坦,但他的语言精粹并不适合初学者学习。即便如此,在后面我还是会建议把当做补充的学习资源。但目前为止,依然是学习编程的好帮手。周正则表达式,对象,事件,阅读权威指南第,,,章。 既然你找到这篇文章来,说明你是真心想学好JavaScript的。你没有想错,当今如果要开发现代网站或web应用(包括互联网创业),都要学会JavaScript。而面对泛...
摘要:这是我收集的一些资源,分享给大家,全部放在百度网盘,有需要的请转存到自己的网盘或者下载,以免网盘链接失效,另外还有几百的视频文件存在网盘,需要的加全部分享在空间,自己可以去下载与权威指南配套源码禅意花园高清源码基础教程权威指南参考手册锋利 这是我收集的一些资源,分享给大家,全部放在百度网盘,有需要的请转存到自己的网盘或者下载,以免网盘链接失效,另外还有几百G的视频文件存在网盘,需要的加...
摘要:写在前面目前专注深入学习,特花了点时间整理了一些前端学习相关的书籍。大致分为以下大系列系列系列基础系列应用系列进阶系列类库系列框架系列。这些书籍在这里免费提供下载,有兴趣的一起学习。 写在前面 目前专注深入JavaScript学习,特花了点时间整理了一些前端学习相关的书籍。 大致分为以下7大系列:CSS系列、DOM系列、JavaScript基础系列、JavaScript应用系列、Ja...
阅读 2206·2021-09-24 10:31
阅读 3808·2021-09-22 15:16
阅读 3359·2021-09-22 10:02
阅读 983·2021-09-22 10:02
阅读 1782·2021-09-08 09:36
阅读 1955·2019-08-30 14:18
阅读 590·2019-08-30 10:51
阅读 1847·2019-08-29 11:08