JavaScript面向对象编程指南(第2版)》读书笔记

一、对象

1.1 获取属性值的方式


water = {
  down: false
}
console.log(water.down) // false
console.log(water['down']) // false

1.2 获取动态生成的属性的值


var type = 'down'
console.log(water[type]) // false

二、数组

2.1 检测是否为数组


typeof([1,2])  // object
Array.isArray([1,2])  // true
Object.prototype.toString.call([1,2])  // [object Array]
Array.isArray(Array.prototype)  // true
Object.prototype.toString.call(Array.prototype)  // [object Array]

2.2 增加数组长度导致未赋值的位置为undefined

减少数组长度则会裁去多余的值。


var x = [1,2];
x.length = 7;
console.log(x);  // [1, 2, undefined × 5]
x.length = 1;
console.log(x);  // [1]

2.3 用闭包实现简易迭代器


var next = setup([3,3,9]);
function setup(x){
  var i = 0;
  return function(){
    console.log(x[i++]);
  }
}
next();  // 3
next();  // 3
next();  // 9
next();  // undefined

三、作用域

3.1 函数作用域(局部变量)

不能在函数体外直接访问函数内变量。


function water() {
 var direction = 'down'
}
console.log(direction)  // Uncaught ReferenceError: direction is not defined

3.2 不存在块级作用域

for、if等代码块中的变量不是局部变量。


if(water){
  var down = true
}
console.log(down)  // true

3.3 变量泄露

函数体内的变量未声明,会在函数第一次执行的时候泄露成全局变量。


function water() {
  direction = 'down'
}
water()  // 执行函数
console.log(direction)  // down

3.4 变量提升

已声明的变量名会提升至顶部,值不会提升。


var down = true
function water() {
  // 变量提升覆盖了外部down,由于值没有提升,所以为undefined
  console.log(down)  // undefined
  var down = false  // false
  console.log(down)
}
water()

3.5 临时作用域


call和apply借用另一个对象的方法,提高代码复用
第一个参数为this的指向,第二个参数为传入的参数,apply传入数组
构造函数不使用new this的值会指向window

四、闭包

4.1 操作闭包中的值


var nature = (function() {
  var water = {}
  water.down = false
  water.get = function(type) {
    return water[type]
  }
  water.set = function(type,val) {
    water[type] = val
    return typeof(val) === 'boolean' ? true : false
  }
  return {
    getWater: water.get,
    setWater: water.set
  }
})()
console.log(nature.getWater('down'))  // false
console.log(nature.setWater('down',true))  // true

五、事件监听


var event = {
  add: function ( dom,type,func ) {
    if(window.addEventListener){
      dom.addEventListener( type,func,false )
    }
    // 兼容IE9以下
    else if(document.attachEvent) {
      dom.attachEvent('on' + type,func)
    }
    else {
      dom['on' + type] = func
    }
  },
  del: function ( dom,type,func ) {
    if(window.addEventListener){
      dom.removeEventListener( type,func,false )
    }
    else if(document.attachEvent) {
      dom.detachEvent('on' + type,func)
    }
    else {
      dom['on' + type] = null
    }
  }
}
var f = function(){
  console.log('event received')
}
event.add(document.body,'click',f)
event.del(document.body,'click',f)

六、类型检测

6.1 常用类型


typeof(1)  // "number"

number/boolean/string/undefined/object/function

6.2 继承检测


function Water (name,status) {
  this.name = name
  this.status = status
}
var seaWater = new Water('sea','warm')
seaWater instanceof Water  // true

6.3 NaN和isFinite检测

NaN不等于NaN,检测需要使用isNaN函数。

NaN === NaN  // false
isNaN(NaN)  // true

七、类型转换

7.1 转为整形

parseInt和parseFloat碰到第一个异常字符就会终止。


console.log(parseInt(66.5t))  // 66.5
console.log(parseInt(t66.5t))  // NaN

7.2 null和undefined

数值超出范围则显示Infinity。


console.log(1*undefined)  // NaN
console.log(1*null)  // 0

八、URL编码

8.1 编码


var src = "http://www.cnblogs.com/bergwhite/p/6657943.html"
var srcURI = encodeURI(src)  // "http://www.cnblogs.com/bergwhite/p/6657943.html"
var srcURICom = encodeURIComponent(src)  // "http%3A%2F%2Fwww.cnblogs.com%2Fbergwhite%2Fp%2F6657943.html" 

8.2 解码


decodeURI(srcURI)  // "http://www.cnblogs.com/bergwhite/p/6657943.html"
decodeURIComponent(srcURI)  // "http://www.cnblogs.com/bergwhite/p/6657943.html"

九、JSON格式

9.1 转为JSON格式


var water = {
  down: false
}
var waterJSON = JSON.stringify(water)  // "{"down":false}"

9.2 转为对象


JSON.parse(waterJSON)  // Object {down: false}

十、兼容性问题


parseInt(09) // ES5中默认不转换八进制,ES3会默认作为八进制
parseInt(09,10)  // 当值为日期的时候,作为十进制处理

感谢大家的阅读。

 

 

 

 

一、基本类型

1.1 字符串

判断是否包含某个字符串

indexOf方法中,找到相关字符串会返回第一次出现的下标。没有找到就会返回-1,利用这个特性可以判断字符串是否存在。


console.log('Fine'.indexOf('in') !== -1)  // true

把字符串按照一定规则分离成数组

下面是以空格为分割标志。


console.log('I seek you'.split(' '))  // ["I", "seek", "you"]

复制指定位置的字符串

传入的两个参数分别是开始的位置和结束的标记。看清楚,第二个参数本身的小标所表示的内容不会被复制,第二个参数是用来标记,这里是结束位置。


console.log('I seek you'.slice(2,6))  // seek
console.log('I seek you'.substring(2,6))  // seek

拼接字符串


console.log('I seek you'.concat(' too.'))  // I seek you too.

查看字符串中的字符


console.log('I seek you'[0])  // I
console.log('I seek you'.charAt(0))  // I

1.2 对象

判断属性是自己的还是继承来的

使用in不能判断属性是自己的还是继承来的,使用hasOwnProperty可以。


var xiaoming = {
  name: 'xiaoming'
}
使用in不能判断属性是自己的还是继承来的
---------------------------------
'name' in xiaoming  // true
'toString' in xiaoming  // true
---------------------------------
xiaoming.hasOwnProperty('name')  // true
xiaoming.hasOwnProperty('toString')  // false

判断对象是否可枚举


xiaoming.propertyIsEnumerable()  // false

判断对象是另一个对象的原型


var People = function (name) {
    this.name = name
}
var xiaoming = new People('xiaoming')


Human.prototype = monkey
monkey.isPrototypeOf(man)

1.3 原型

  • __proto__是实例对象的属性
  • prototype是构造函数的属性
  • constructor指向构造函数

IE中不存在__proto__,推荐使用ES5的Object.getPropertyOf()访问。


typeof [].__proto__  // "object"
Object.getPrototypeOf([])  // [constructor: function, toString: function, toLocaleString: function, join: function, pop: function…]
[].constructor.prototype

原型继承


var People = function (name,age) {
  this.name = name
  this.age = age
}
xiaoming = People.prototype
xiaoming.constructor = xiaoming

1.4 常用数学方法


Math.PI  // 3.141592653589793
Math.SQRT2  // 1.4142135623730951
Math.sqrt(2)  // 1.4142135623730951
Math.E  // 2.718281828459045
Math.pow(2,3)  // 8
Math.random() * (10-2)+2  // 7.564475903879611 | 2-8之间的平均数
Math.LN2  // 0.6931471805599453
Math.floor(2.6)  // 2 | 指定值的最小整数
Math.ceil(2.6)  // 3 | 指定值最大整数
Math.round(2.6)  // 3 | 去最靠近指定值的整数
Math.max()  // 3
Math.min()  // 2
Math.sin(90)  // 0.8939966636005579
Math.cos(90)  // -0.4480736161291702

二、DOM操作

2.1 节点编号、名称以及值

nodeType有12种,具体请见MDN


<div class="you">HELLO YOU</div>

var you = document.getElementsByClassName('you')[0]
you.nodeType  // 1
you.nodeName  // BIV
you.nodeValue  // null
you.textContent  // HELLO YOU
you.innerText  // "HELLO YOU"

2.2 父节点、子节点和相邻节点

检查是否具有某个子节点


document.documentElement.hasChildNodes('body')  // true

查看所有子节点


document.documentElement.childNodes  // [head, text, body]

查看第一个子节点


document.documentElement.firstChild  // <head>...</head>

访问父节点


document.documentElement.childNodes[0].parentNode

访问相邻节点


document.documentElement.children[0].previousSibling  // null
document.documentElement.children[0].nextSibling  // #text

2.3 添加和删除节点


<div class="you">HELLO YOU</div>

var you = document.getElementsByClassName('you')[0]

新建节点


var pTag = document.createElement('p')
var pVal = document.createTextNode('HELLO YOU')
pTag.appendChild(pVal)  // <p>HELLO YOU</p>

添加节点


document.body.insertBefore(pTag,you)
document.body.replaceChild(you,pTag)

删除节点


document.body.removeChild(you)

克隆节点

true为深拷贝,会拷贝节点的内容。flase只拷贝空标签。


var newNodeFalse = document.body.cloneNode(true)
var newNodeFalse = document.body.cloneNode(false)
console.log(newNodeFalse)  // <body>...</body>
console.log(newNodeFalse)  // <body></body>

2.4 属性相关


<div class="you">HELLO YOU</div>

var you = document.getElementsByClassName('you')[0]

检查是否具有某个属性


you.hasAttributes('class')  // true

获取具体属性


you.getAttribute('class')  // "you"
you.attributes[0].nodeValue  // "you"
you.attributes['class'].nodeValue  // "you"

选择器

querySelector使用的是CSS选择器,返回单个节点。返回所有匹配的结果用querySelectorAll。


document.querySelector('.you')
document.querySelectorAll('.you')  // [div.you]

批量添加样式


you.style.cssText = "color:red;font-size:200px;"

2.5 DOM合集


document.images
document.applets
document.links
document.anchors
document.forms
document.cookie
document.title
document.referrer
document.domain

2.6 DOM遍历


function walkDOM(n){
  do {
    console.log(n)
    if(n.hasChildNodes()){
      walkDOM(n.firstChild)
    }
  }
  while (n=n.nextSibling)
}
walkDOM(document.body)

三、其他

3.1 事件

阻止冒泡


event.stopPropagation()
window.event.cancelBubble = true  //IE

阻止默认事件


event.preventDefault()
return false  // IE

拖动事件

MDN在线示例

触屏事件

这里有一个用canva实现的画图页面,触屏画图,实现过程可以直接看源码。。另外触屏事件的分析,请见伯乐在线


touchstart
touchmove
touchend
touchleave
touchcancel

3.2 浏览器检测

用户代理可以被模拟,所以根据浏览器的不同特征来检测当前浏览器类型更加可靠。


if(window.addEventlistener) {
    // code...
}
else if(){
    // code...
}

3.3 三种弹窗方式

三种弹窗分别是提示框(alert),确认框(confirm)和交互框(prompt)。可以把确认和交互赋值给变量,变量会存储相应结果。


alert('Welcome To JS!')
var isLike = confirm('Do you like JS?')
var whyLike = prompt('Why do you like it.')
console.log(isLike)  // true
console.log(whyLike)  // Maybe...

3.4 根据浏览器历史控制前进后退

根据缓存的浏览器历史,可以控制前进、后退和跳转到指定历史记录。


window.history.forward()  // 前进
window.history.back()  // 后退
window.history.go(1)  // 跳转

3.5 重载页面的六种方式


location.reload()
location.assign('/')
location.replace('/')
window.location.href = '/'
location = location
window.location.reload()

3.6 修改当前页面URL但是不刷新页面


history.pushState({a:1},'','hello')

3.7 URI编码


function decodeURI(url,params){
  var url = url || 'http://www.cnblogs.com/bergwhite/'
  var params = params || {name: 'berg', age: 22}
  var query = []
  for (param in params) {
    query.push(param+'='+params[param])
  }
  return url+=query.join('&')
}
decodeURI() // "http://www.cnblogs.com/bergwhite/name=berg&age=22"
decodeURI('http://www.you.com/',{a:1,b:2})  //  "http://www.you.com/a=1&b=2"

3.8 窗口相关

新窗口打开内容


window.open('http://www.baidu.com','zzzzzzzzzzzz','width=800px,height=300px,resizable=yes')

判断是否是高分辨率屏幕


window.devicePixelRatio  // 1

感谢您的阅读。

posted @ 2017-05-04 23:32  最骚的就是你  阅读(905)  评论(1编辑  收藏  举报