《js语言精粹》笔记(5-8章)

132 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情

阅读《JavaScript语言精粹》(修订版)的笔记记录,这里是5-8章的笔记,书虽然老了,但了解一下并不会吃亏。

第五章 继承

  • 继承好处:1,代码重用 2,引入一套类型系统的规范,无需编写显式类型转换的代码,工作量降低,类型转换会丧失类型系统在安全上的优势

  • 伪类 Child.prototype = new Parent(),伪类是先声明了Child的构造函数

  • 简单的继承 var Child = Object.create(Parent)

    Object.create = (o)=>{
    	let F = function(){}
    	F.prototype = o
    	return new F()
    }
    和上面的伪类其实也没多大区别,原型继承是先继承再修改,叫做差异化继承。
    
  • 函数化模式 没用new ,更好的封装和信息隐藏,访问父类方法

    var mammal = function(spec){
    	var that = {}
    	that.get_name = function(){return spec.name}
    	return that
    }
    var myMammal = mammal({name:'a'})
    -- 继承
    var cat = function(spec){
    	var that = manmal(spec)
    	that.xx = ..
    	//super
    	var sup_get = function(){return that.get.apply(that,argument)}
    	return that
    }
    

第六章 数组

  • 数组是一段线性分配的内存,但js没用这种数据结构,所以用对象来模拟,不过我们用起来没差就是了。

  • js数组允许包含混合类型的值

  • length是数组最大整数属性值+1,不一定就等于数组里的属性个数

  • 可以直接设置length,不会给数组分配更多的空间,但是下标大于length的属性会被删除

  • 由于数组本质是对象,可以用delete number[2]来删除属性,但这样number会留下一个空洞,[0,1,undefinded,3],应该用splice

  • js对数组和对象的区别是混乱的,typeofobject,要用Object.prototype.toString.apply(value)==='[object Array]'

  • 初始值,这书的做法已经老了

    一维
    书:var a = [];for(var i=0;i<x;i++){a[i]=x}
    new Array(3).fill(初始值)
    二维
    书:for(var i=0;i<x;i++){a[i]=[]}
    Array.from(new Array(x),()=>new Array(y).fill(z))
    

第七章 正则

正则我有好好学过,然后全还回去了。所以我觉得就记记笔记,要编啥再拿出来用。能用startWith/indexOf/splice完成的事就不要劳烦正则了。

这里讲的也不是很详细,具体还是要看其他书,如正则小册

  • /^(1)?(2)/.exec(url)会匹配出两个结果,一个括号一个结果,匹配的字符串放0,其他结果放1,2,3
  • g表示全局匹配,i表示忽略字符大小写
  • |来分隔多个正则表达式序列, "into".match(/in|int/)匹配出 in
  • 表达式因子要匹配特殊字符 如 \ / { }要在前缀加/来转义
  • \d表示一个数字 [0-9]\D表示 [^0-9],还有 \s \w其他转义
  • 正则表达式分组有四种,(我看不懂)

捕获型:() () 匹配分组

非捕获型:(?:前缀) 简单的匹配

向前正向匹配:(?=前缀) 类似非捕获,匹配后文本会倒回开始的地方

向前负向匹配:(?!前缀) 匹配失败才会继续匹配

  • 正则表达式字符要转义的字符 - / [ \ ] ^
  • 正则表达式因子前面可以用一个正则表达式量词来决定这个因子要匹配的次数,?表示0或1,*表示{0,}0或多 , +表示{1,},/www/=/w{3}/

第八章 方法

数组

  • array.concat添加元素;不改原数组,产生一个新数组,参数多个,可以是数组或者元素,追加到它后面 [].concat([1,2],3) = [1,2,3]

  • array.join 数组转成字符串;[1,23,3].join()='1233,[1,23,3].join(',')='1,23,3'

  • array.pop(推出队尾),push(推入队尾,和concat一样,但他会改原数组),reverse(反转),shift(推出队头),unshift(推入队头)

  • array.slice(start,end)

    end可选,截取序列从start到end-1的数组。

    end无,就截到最后。

    start大于数组长度,得到空数组。

    如果参数有负数,会和数组长度相加。

  • array.sort排序,他把元素都当成字符串,所以不能直接用来排序数字。简单的排序数字:n.sort((a,b)=>a-b)

  • array.splice(s,d,i1,i2,i3) 移除元素并用新元素替换;s开始,删除 d个元素,替换成 i1,i2

Number

  • Number.toExponential(fractionDigits)number转成一个指数形式的字符串,fractionDigits必须在0-20,代表小数点后数字位数 Math.PI.toExponential(2)=3.14e+0

  • number.toFixed(fractionDigits)转换成十进制的字符串,参数是小数点后数字位数,无参数表示无小数点

  • number.toPrecision(precision)同上,无参数默认为16位,不填充0 记tofixed 应该就够了

  • Number.toString(radix) 参数为2-36,转化进制,默认10,无参数可以简写String(number)

RegExp

  • exec是最强大也最慢的方法,匹配成功后会返回一个数组,索引0是匹配的子字符串,1是分组1捕获的元素,以此类推。如果正则带g标识,查找会从regexp.lastIndex位置开始,默认为0,匹配成功后会改成匹配后第一个字符的位置,可以通过循环调用去查询一个匹配模式在一个字符串中发生了几次,如果提前跳出循环,再进入循环必须把 regexp.lastIndex重置一下。

    while(a=tags.exec(text)){
    	a.forEach(i=>console.log(i))
    }
    //vue模板如{{}}的渲染就有用到这个
    
  • regexp.test 匹配了就是true

String

.charAt(pos) 返回参数位置的字符,参数小于0或大于等于length,返回空字符串。 =slice(pos,pos+1)

.charCodeAt(pos) 位置的字符转成字符码位;参数小于0或大于等于length,返回NaN'Cu'.charCodeAt(0)=67

.localeCompare(that)比较两个字符串,基本没用,小返回-1,相等返回0,大返回1

.match(regexp)exec类似,这个可以带g标识,得到所有匹配的数组。不带就只匹配一次。捕获分组不加入

.replace(searchValue,replaceValue)查找替换返回新字符串,

searchValue是正则匹配,想全局替换记得加g,

replaceValue可以是字符串或函数,字符串$有特殊含义,

模式对应的替换值
$$在替换位置插入”$”
$&在替换位置插入匹配到的子字符串
$`在替换位置插入在匹配到的字符串前面的子字符串
$’在替换位置插入在匹配到的字符串后面的子字符串

函数时,第一个参数是匹配的字符串,此后的参数是捕获分组匹配的文本。

.search(regexp)indexOf类似

slice和数组的一致

split(separator,limit)和数组的join相反, limit表示被切割的数量

123.split('')=["1","2","3"]

"192.168".split('.')=['192','168]

参数可以是正则,分组捕获的也在分割后的数组内

substringslice一样,但不要用这个

.toLocaleLowerCase()返回一个新字符串,用本地化的规则把里面所有字母转化成小写,主要用在土耳其语上,比较特殊,相反有toLocaleUpperCase

toLowerCasetoUpperCase 所有字母转化成小写和大写

fromCharCode(char) 根据一串数字编码返回一个字符串 String.fromCharCode(67,97,116)='Cat'

代码风格

  • 优秀的程序拥有一个前瞻性的结构,它会预见到未来才可能需要的修改(就是可扩展性吧),但不会让其成为过度的负担
  • 优秀的程序具有清晰的表达方式,就能更容易的理解和改造修补它。
  • 比如在诸如if,while的结构化语句里,始终使用代码块
  • 对一个脚本应用或工具库,只用一个全局变量,每个对象都有它自己的命名空间(现在模块化了)

还是太泛了,还是看阮一峰的吧

es6.ruanyifeng.com/?search=Ref…