《JavaScript语言精粹》读书笔记

第三章 对象

  • 检索
  var obj = {a: 1, b:2, c:3}
obj[a] // obj.a
// 检索结果是undefined 时用 || 或 && 避免错误
obj[a] && obj[b]
  • 反射
var obj = {
  number: 111,
  airline: 'dsdsds'
}

// hasOwnProperty检测对象的属性
console.log(typeof obj.number) // number
console.log(obj.hasOwnProperty('number')) // true
console.log(obj.hasOwnProperty('number1')) // false

  • 枚举

第四章 函数

调用

js中一共有4中调用模式:

  1. 方法调用模式
  2. 函数调用模式
  3. 构造器调用模式
  4. apply调用模式
	//1 方法调用模式
	var myObject = {
		value: 0,
		increment: function(inc) {
			this.value += typeof inc === 'number' ? inc: 1;
		}
	}
	myObject.increment();
document.writeln(myObject.value)/// 1
	myObject.increment(2);
	document.writeln(myObject.value) // 3
	
	// 方法可以使用this访问自己所属的对象,所以他能从对象中取值或者对对象进行修改。
	// this到对象的绑定发生在调用的时候。
  1. 函数调用模式
		//2 函数调用模式
		var add = function(a, b) {
			return a+ b;
		}
		var sum = add(3, 4); // 7

			// 给myObject 增加一个double方法
		myObject.double = function() {
			var that = this;
			var helper = function () {
				that.value = add(that.value, that.value);
			}
			helper(); // 以函数的形式调用helper
		}
		// 以方法的形式调用double
		myObject.double();
		console.log(myObject.value) // 6
		// 方法调用函数时,this被绑定到全局对象, 解决方案 : 定义一个变量,将this赋值给它,name内部函数就可以通过that访问到this
  1. 构造器调用模式 不推荐
		//3 构造器调用模式 不推荐
		var Quo = function(string) {
			this.status = string;
		}
		// 给quo的所有实例提供一个名为get_status的公用方法
		Quo.prototype.get_status = function() {
			return this.status;
		}

		// 构造一个quo的实例
		var myQuo = new Quo('confused');
    document.writeln(myQuo.get_status()) // confused
    // 如果在一个函数前面带上new 来调用,那么背地里将会创建一个连接到该函数的prototype成员的新对象,同时this会被绑定到那么新对象上。

  // 使用闭包的方法来调用
    var quo = function(status) {
    return {
      get_status: function() {
        return status
      }
    }
  }
  var myQuo = quo('amazed')
  console.log(myQuo.get_status()) //amazed
  1. Apply调用模式
		// 4 Apply调用模式
		// Apply方法让我们构建一个参数数组传递给调用的函数,它允许我们选择this的值。apply方法接收两个参数,第1个是要绑定给this的值,第2个就是一个参数数组

		var array =[3, 4];
		var sum = add.apply(null, array);
		alert(sum) // 7
		// 构造一个包含status成员的对象
		var statusObject = {
			status: 'A-OK'
		}
		// statusobject并没有继承自Quo.protoptype,但我们可以在statusobject上调用
		// get_status方法,尽管statusObject并没有一个名为get_status的方法
		var status = Quo.prototype.get_status.apply(statusObject);
		console.log(status) // A-OK
扩充类型功能
    
    // js允许给语言的基本类型扩充功能; 可以给object。prototype添加方法,可以让该方法对所有对象都可用。
    // 这样的方式对函数,数组,字符串,数字,正则表达式和布尔值同样适用
    Function.prototype.method= function(name, func) {
      this.prototype[name] = func
      return this
    }
    // 通过给function.prototype 增加一个method方法,我们下次给对象曾加方法的时候就不必键入prototype这几个资产,省略掉了一点麻烦
    // 1 给Number.prototype 增加一个integer方法来改善它,他会根据数字的正负来判断是使用Math.ceiling 还是Math.floor
    Number.method('integer', function() {
      return  Math[this<0 ? 'ceil': 'floor'](this)
    })
    document.writeln((-10/3).integer()) // -3
作用域
var foo = function() {
	var a =3, b=5;
	var bar = function() {
		var b=7, c=11;
		// a =3 b =7 c=11
		a+=b+c // a=21 b=7 c= 11
	}
	// a=3 b=5 c undefined
	bar()
	// a=21 b 5
}
闭包
    // 创建一个名为quo的构造函数
    // 它构造带有get_status方法和status私有属性的一个对象
    var quo = function (status) {
      return {
        get_status: function () {
          return status
        }
      }
    }
    // 构造一个quo实例
    var myQuo = quo('amazed')
    console.log(myQuo.get_status()) //amazed
    // 这个quo函数设计成无需再前面加上new来使用,所以名字也没有首字母大写。当我们调用quo时,它返回包含
    // get_status方法并不是访问该参数的一个副本,它访问的就是该参数本身。这是可能的;
    // 因为该函数可以访问它被创建时所处的上下文环境。  这就称为闭包。
// 定义一个函数,它设置一个DOM节点为黄色,然后把它渐变为白色
var fade = function (node) {
      var level = 1;
      var step = function () {
        var hex = level.toString(16);
        node.style.backgroundColor = '#FFFF' + hex + hex;
        if (level < 15) {
          level += 1;
          setTimeout(step, 100);
        }
      }
      setTimeout(step, 100);
    }
    fade(document.body) 
记忆
 // 函数可以将先前操作的结果记忆在某个对象里,从而避免无谓的重复运算。这种优化被称为记忆
    // 实现一个递归函数来计算Fibonacci数列
    // 一个斐波那契数列 数字是之前两个斐波那契数字之和。 最前面的两个数字是0 和1 
    var fibonacci = function(n) {
      return n<2 ? n : fibonacci(n-1) +fibonacci(n-2)
    }
    for(var i=0;i<=10; i+=1){
      document.writeln('//'+i+':' +fibonacci(i))
      //0:0 //1:1 //2:1 //3:2 //4:3 //5:5 //6:8 //7:13 //8:21 //9:34 //10:55
    } 
    // 优化
    // 我们在一个名为memo的数组里保存我们的存储结果,存储结果可以隐藏在闭包中。当函数被调用时,
    // 这个函数首先检查结果是否已存在,如果已经存在,就立即返回这个结果。
    var fibonacci =function(n) {
      var memo = [0,1]
      var fib=function(n) {
        var result =memo[n]
        if(typeof result !== 'number') {
          result = fib(n-1) +fib(n-2)
          memo[n]=result
        }
        return result
      }
      return fib
    }()
    for(var i=0;i<=10; i+=1){
      document.writeln('//'+i+':' +fibonacci(i))
      //0:0 //1:1 //2:1 //3:2 //4:3 //5:5 //6:8 //7:13 //8:21 //9:34 //10:55
    }
    // 推广
    // 我们memoizer函数取得一个初始化memo数组和formula函数。它返回一个管理meno存储和在需要时调用formula函数的recur函数。
    // 我们把这个recur函数和它的参数传递给formula函数
    var memoizer =function (memo, formula){
      var recur = function(n){
        var result = memo[n]
        if(typeof result !== 'number') {
          result = formula(recur, n)
          memo[n] =result
        }
        return result
      }
      return recur
    }
    // 现在,我们可以使用memoizer函数来定义fibonacci函数, 提供其初始的memo数组和formula函数
    var fibonacci = memoizer([0,1], function(recur, n) {
      return recur(n-1) +recur(n-2)
    })

    var factorial = memoizer([1,1], function(recur, n) {
      return n * recur(n-1)
    })

js易混淆的地方

    // 区分数组和对象
    var is_array = function(value) {
      return Object.prototype.toString.apply(value) === '[object Array]'
    }
    console.log(is_array([])) // true

第八章 方法

Array
  • array.concat()
    // concat方法产生一个新数组,它包含一份array的浅复制并把一个或多个参数item附加在后面,如果参数item是一个数组
    // name它的每个元素会被分别添加 类似于 array.push()
    var a = [1,2,3]
    var b= [4,5,6]
    console.log(a.concat(b, true)) //[1, 2, 3, 4, 5, 6, true]
  • array.join()
  • array.pop()
    // pop移除数组中最后一个元素并返回改元素,如果array是空,它返回undefined
    var a = [1,2,3]    
    var c= a.pop()
    console.log(c) // 3
    console.log(a)
  • array.push()

  • array.reverse()

  • array.shift()

  • array.slice()

  • array.sort() 排序

    var n = [4,6,7,1,5]
    n.sort(function(a,b) {
      return a-b
    })
    console.log(n) // [1, 4, 5, 6, 7]

    var m = ['aa','bb', 'a', 4,8,16,23,42]
    m.sort(function(a, b) {
      if(a ===b) {
        return 0
      }
      if(typeof a === typeof b) {
        return a< b? -1 : 1
      }
      return typeof a <typeof b ? -1 :1
    })
    console.log(m) //[4, 8, 16, 23, 42, "a", "aa", "bb"]
  • array.splice()
  • array.unshift()
Function
  • function.apply(thisArg, argArray)
    apply方法调用function,传递一个会绑定到this上的对象和一个可选的数组作为参数。
    apply方法被用在apply调用模式中
    Function.method('bind', function(that) {
      // 返回一个函数,调用这个函数就像调用那个对象 的一个方法
      var method = this,
      slice = Array.prototype.slice,
      args = slice.apply(arguments, [1])
      return function() {
        return method.apply(that, args.concat(slice.apply(arguments, [0])))
      }
    })
    var x = function() {
      return this.value
    }.bind({value: 666})
    alert(x())
  • object.hasOwnProperty(name)
    如果这个object包含一个名为name的属性,n那么hasOwnProperty方法返回true
RegExg

regexp.exec(string)
如果匹配成功regexp和字符串string,它会返回一个数组。
数组中的下标未0的元素将包含正则表达式regexp匹配的子字符串

  • regexp.test(string)
    返回 true 和false
String
  • string.charAt()
  • string.charCodeAt()
  • string.concat()
  • string.indexOf()
    返回 -1 未找到 找到返回位置
  • string.lastIndexOf()
  • string.match(regexp)
    字符串和正则匹配 和全局匹配 g
  • string.replace(searchValue, replaceValue)
    对string进行查找和替换操作,并返回一个新的字符串。
var reg = /\((\d{3})\)/g
var p = '(555)666-1212'.replace(reg, '$1-')
console.log(p) //555-666-1212
  • string.search(regexp)
    search方法和indexOf方法类似,接收一个正则表达式对象作为参数而不是一个字符串
    找到匹配 返回第一匹配的位置,没有返回-1
var text = 'and in it he says "Any damn fool could'
var pos = text.search(/["']/) // 18
  • string.slice(start, end)
    如果start/end是负数,他将与string.length相加。end参数是可选参数,默认string.length
  • string.split(separator, limit)
    把string分割成片段来创建一个字符串数组。
  • string.substring(start, end)
    和slice()的用法一样, 不能处理负数参数
  • string.toLocaleLowerCase()
  • string.toLocaleUpperCase()
posted @ 2019-01-13 20:39  甜土豆  阅读(125)  评论(0编辑  收藏  举报