[读书笔记]javascript语言精粹'

人比较笨,以前只做项目,案例,然而一些javascript的很多理论不知道该怎么描述,所以最近开启一波读书之旅;

标识符

1、定义
标识符以字母开头,可能后面跟上一个或多个字母、数字或者下划线。

2、用处
标识符被用于语句、变量、参数、属性名、运算符以及标记。

数值

1、数值在内部被表示为64位的浮点数;

2、NaN是一个数值,但是它不与任何值,包括它自己,即 NaN !== NaN 为 true;

3、isNaN可以检查数值是否为NaN;

4、方法:

number.toExponential()

toExponential 方法把number转换成一个指数形式的字符串。可选参数控制小数点的数字位数;

var num = Math.PI;
console.log(num.toExponential(0));//3e+0
console.log(num.toExponential(2));//3.14e+0
console.log(num.toExponential(7));//3.1415927e+0
console.log(num.toExponential(16));//3.1415926535897931e+0
console.log(num.toExponential());//3.141592653589793e+0

number.toFixed()

toFixed 方法把number转换成一个十进制形式的字符串,可选参数控制小数点的数字位数,默认为0;

console.log(num.toFixed(0)); //3
console.log(num.toFixed(2)); //3.14
console.log(num.toFixed(7)); //3.1415927
console.log(num.toFixed(16)); //3.1415926535897931
console.log(num.toFixed());  // 3

number.toString

toString 方法把number转换成一个字符串。可选参数控制基础,2~36之间,默认为10,参数为多少,就转换成几进制的字符串

console.log(num.toString(2));//11.001001000011111101101010100010001000010110100011
console.log(num.toString(8));//3.1103755242102643
console.log(num.toString(10));//3.141592653589793
console.log(num.toString(16));//3.243f6a8885a3
console.log(num.toString()); //3.141592653589793

字符串

1、因为Unicode是一个16的字符集,所以Javascript中的所有字符串都是16位的;

2、Javascript中没有字符类型,用一个引号就可以表示一个字符串;

3、字符串有长度:‘str’.length = 5;

4、字符串一旦创建时不可变得,但是可以用 += 运算符与其他字符连接,创建一个新的字符串;

5、方法

string.charAt(i)

charAt 方法返回在string中i位置处的字符,如果i小于0或大于等于字符串的长度,则返回空字符串;

var name = 'Tom';
var a = name.charAt(1);

console.log(a); //o

实现:

String.prototype.charAter = function(i){
    return this.slice(i,i+1);
}

string.concat()

concat 方法把其他字符串连接在一起来构成一个新的字符串,很少被用;

var str = 'Tom';
var name = str.concat('and','Jerry');
console.log(name); //Tom and Jerry

string.indexOf(searchStr,p) && string.lastIndexOf(searchStr,p)

indexOf 方法在string内查找另一个字符串searchStr,如果被找到,返回第一个匹配字符的位置,否则返回-1;可选参数p可以设置从string的某个指定位置开始查找;

var test = 'Mississippi';
var str1 = test.indexOf('ss');
var str2 = test.indexOf('ss',3);
var str3= test.indexOf('ss',6);

console.log(str1); //2
console.log(str2); //5
console.log(str3); //-1

lastIndexOf 与 indexOf 方法类似,只不过它是从字符串的末尾开始查找;

var str4 =test.lastIndexOf('ss');
var str5= test.lastIndexOf('ss',3);
var str6 = test.lastIndexOf('ss',6);

console.log(str4); //5
console.log(str5); //2
console.log(str6); //5

string.localeCompare(str1)

localeCompare方法比较两个字符串,如果string 比字符串str1小,返回负数,如果相等,返回0;

var a = 'abc';
var b = 'ABC';
console.log(a.localeCompare(b));//-1

var arr = ['AAA','A','aa','Aa','aaa','a'];
arr.sort(function(a,b){
    return a.localeCompare(b);
});
console.log(arr);//["a", "A", "aa", "Aa", "aaa", "AAA"]

string.match(reg)

match 方法让字符串和一个正则表达式精选匹配;

string.replace(searchStr,replaceStr)

replace 方法对string进行查找和替换操作,并返回一个新的字符串。参数searchStr可以是个字符串或正则表达式对象。如果是个字符串,那么searchStr只会在第一次出现的地方诶替换;

var str = 'monther_in_law';
var result = str.replace('_','-');
console.log(result);//monther-in_law

replaceStr 可以是一个字符串或函数,如果是个字符串,字符 $ 拥有特殊含义;

美元符号序列 替换对象
$$ $
$& 整个匹配的文本
$number 分组捕获的文本
$` 匹配之前的文本
$' 匹配之后的文本

string.search(reg)

search方法与indexOf方法类似,它接受一个正则表达式,如果匹配到,返回第一个匹配的位置,否则,返回-1;

string.slice(start,end)

slice 方法复制string的一部分,来构造一个新的字符串;如果start参数是负数,他将与string.length相加,end参数可选,默认为string.length;

string.split(s,l)

splice方法把string分割成片段,来创建一个字符串数组,s是可以是一个字符串或者正则表达式,l是可选的,限制数量

string.subString(start,end)

subString方法与slice方法一样,它不能处理负数;

string.toLocaleLowerCase()

toLocaleLowerCase 方法使用本地化规则,将string中的所有字母转换为小写格式;

string.toLocalUpperCase()

toLocaleUpperCase 方法使用本地化规则,将string中的所有字母转换为大写格式;

string.toLowerCase()

toLowerCase 方法将string中的所有字母转换为小写格式;

string.toUpperCase()

toUpperCase 方法将string中的所有字母转换为大写格式;

String.fromCharCode()

String.fromCharCode 函数根据一串数字编码返回一个字符串;

布尔值

1、false值
false
null
undefined
空字符串
数字0
数字NaN

2、其他的都为true值,包括true和字符串‘false’,以及所有对象;

语句

1、通常按照从上到下的顺序被执行;

2、代码块是包在一个对花括号中的一组语句;代码块不会创建新的作用域;

3、for in循环枚举一个对象的所有属性;通常先检查这个属性名是该对象本身的,还是来自原型链的;

for(var attr in object){
    if(object.hasOwnProperty(attr)){
        ...
    }
}

4、switch-case语句中case值可以为任何值;

表达式

1、运算符的优先级

运算符 解释
. [] () 提取属性与调用函数
delete new typeof ! 一元运算符
* / % 乘法、除法、求余
+ - 加法/连接 、 减法
>= <= > < 不等式运算符
=== !== 等式运算符
&& 逻辑与
逻辑非
?: 三元运算符

2、typeof运算符的值

number、string、object、undefined、function、boolean

null或者数组为object

对象

1、定义

对象式属性的容器,其中每个属性都有对应的名字和值;

2、特点

属性名可以是包括空字符串在内的任何字符串;(不能为保留字)

属性值可以是除undefined之外的任何值,包括function;

3、对象字面量

一个对象字面量就是包围在一对花括号中的零或多个‘名/值’对;

4、检索

方式:[]和.

5、更新

对象里的值可以通过赋值语句来进行更新;

6、引用

对象只能通过引用快递,永远不会被复制;

7、枚举

for in循环

8、删除

通过delete运算符来进行对象属性的删除;

var obj = {
    a:1,
    b:2
};

console.log(obj);

delete obj.a;

console.log(obj);

9、方法

object.hasOwnProperty(name)

如果object包含一个名为name的属性,那么hasOwnProperty方法返回true。原型链中的同名属性是不会被检查得。

var obj = {msg:true};
var a = Object.create(obj);
var t = obj.hasOwnProperty('msg');
var _msg = a.msg;
var _t = a.hasOwnProperty('msg');

console.log(t); //true
console.log(_msg);//true
console.log(_t);//false

数组

1、数组字面量

数组字面量提供了一种非常方便的创建数组的表示法;一个数组字面量是在一对方括号中包围零个或多个用逗号分隔的值的表达式;

var arr = [0,1,2,3];

2、特性

JavaScript允许数组包涵任意混合类型的值;

3、长度

每个数组都有一个length属性,javascript数组的length没有上界;

4、删除

delete删除数组元素

var arr = [0,1,2,3,4];
console.log(arr);//[0,1,2,3,4]
delete arr[2];
console.log(arr); // [0,1,undefined,3,4]

splice 删除元素

var arr = [0,1,2,3,4];
console.log(arr);//[0,1,2,3,4]
arr.splice(2,1);
console.log(arr); // [0,1,3,4]

5、判断是否是数组

typeof arr 的类型是 object;

第一种方法:

var is_array = function(value){
    return value && typeof value === 'object'  && value.construcor === Array;
}

第二种方法:

var is_array = function(value){
    return Object.prototype.toString.apply(value) === '[Object,Array]';
}

6、构建矩阵

Array.matrix = function(m,n,initial){
    var a ;
    var b = [];
    for(var i = 0; i < m ;i++){
        a = [];
        for(var j = 0; j < n ; j++){
            a[j] = initial;
        }

        b[i] = a;
    }

    return b;
}

var myMatrix = Array.matrix(4,4,0);
document.writeln(myMatrix[0][0]);//0

7、方法

array.concat()

concat 方法产生一个新数组,先浅复制数组,然后把一个多个参数附加在其后;

var arr1 = [1,2,3,4];
var a = 'a';
var b = 'b';
var arr2 = [5,6,7,8];
var arr3 = [9,10];

var  arr = arr1.concat(a,b,arr2,arr3);
console.log(arr); //[1, 2, 3, 4, "a", "b", 5, 6, 7, 8, 9, 10]

array.join()

join 方法把一个数组构造成一个字符串。默认用“,”好分隔;当数据比较多时,join方法比+运算符要快;

var arr = ['a','b','c','d'];
var str = arr.join();
console.log(str);//a,b,c,d

var str1= arr.join('');
console.log(str1);//abcd

var str2= arr.join('-');
console.log(str2);//a-b-c-d

array.pop()

pop和push方法使得数组array想堆栈一样工作。pop 方法移除array中的最后一个元素,并返回该元素;

var arr = [1,2,3,4,5];
var a = arr.pop();
console.log(arr); // [1,2,3,4]
console.log(a); // 5

实现:

Array.prototype.pop = function(){
    return this.splice(this.length-1,1)[0];
};

array.push()

push 方法把一个或者多个附加到一个数组的尾部。和concat不同,push方法会修改array,返回新数组的长度;

var arr = [1,2,3,4];
var arr2 =['a','b','c','d'];
var len = arr.push(arr2,true);
console.log(arr); // [1,2,3,4,['a','b','c','d'],true]
console.log(len); // 6

实现:

 Array.prototype.push = function(){
    var len  = arguments.length;

    for(var i= 0 ;i<len;i++){
        this.splice(this.length,0,arguments[i])
    }
    return this.length;
}

array.reverse()

reverse 方法反转array里的元素顺序,并返回array本身;

var arr = [1,2,3,4];
var a = arr.reverse();
console.log(a); // [4,3,2,1]

array.shift()

shift 方法移除数组array中的第一个元素并返回该元素;

var arr = [1,2,3,4];
var a = arr.shift();
console.log(arr);//[2,3,4]
console.log(a); //1

实现:

 Array.prototype.shifter = function(){
    return this.splice(0,1);
}

array.slice(start,end)

slice 方法对array中的一段做浅复制。首先复制array[start],一直复制到array[end]为止;end参数可选,默认值是该数组的长度length,如果两个参数中的任何一个是负数,array.length会和她们相机,视图让他们为非负数。

var arr = [1,2,3,4,5];
var a = arr.slice(1,4);
console.log(arr);//[1,2,3,4,5]
console.log(a);//[2,3,4]

array.splice(start,delCount)

splice 方式从array中移除一个或多个元素,并用新的item替换。start是从数组中移除元素的开始位置,delCOunt是要移除的元素个数。如果有额外的参数,则插入到被移除的位置上。返回被移除的数组

var arr = [1,2,3,4,5];
var a = arr.splice(1,2,11,21,22);
console.log(arr);//[1,11,21,22,4,5]
console.log(a);//[2,3]

实现:

Array.prototype.splicer = function (start, count) {
    var argLen = Math.max(arguments.length - 2, 0); //是否有第三个参数
    var len = this.length; //数组长度
    var result = []; //删除数组

    start = start || 0; //第一个参数,开始的位置

    //当start为负数时,加上数组长度length,变为非负数
    if (start < 0) {
        start += len;
    }

    start = Math.max(Math.min(start, len), 0);

    count = Math.max(Math.min(typeof count === 'number' ? count : 0, len-start), 0);

    for (var i = 0; i < count; i++) {
        var element = this[start + i]; //删除的值;
        if (element !== undefined) {
            result[i] = element;
        }
    }

    var itemLen = argLen - count;
    var newLen = len + itemLen;
    var currentIndex = len - start - count;
    if (itemLen < 0) {
        var k = start + argLen;

        for (; currentIndex > 0; currentIndex--) {
            this[k] = this[k - itemLen];
            k++;
        }
    } else if (itemLen > 0) {
        var k = 1;
        for (; currentIndex > 0; currentIndex--) {
            this[newLen - k] = this[len - k];
            k++;
        }
    }
    this.length = newLen;

    for (var i = 0; i < argLen; i++) {
        this[start + i] = arguments[i + 2];
    }

    return result;

}

array.unshift()

unshift 方法用于吧元素插入到array的开始,返回array新的length;

var arr = [1,2,3,4,5];
var a = arr.unshift('a');
console.log(arr);//['a',1,2,3,4,5];
console.log(a);//6

实现:

Array.prototype.unshift = function () {
    var len = arguments.length;
    for (var i = len - 1; i >= 0; i--) {
        this.splice(0, 0, arguments[i]);
    }
    return this.length;
}

array.sort()

sort 方法是对数组array的元素进行排序,由于JavaScript的默认比较函数把要排序的元素都视为字符串,所以sort方法不能正确的排序;

var arr = [2,1,11,5,8,15];
arr.sort();
console.log(arr);//[1,11,15,2,5,8]

修改排序一:

arr.sort(function(a,b){
    return a-b;
});
console.log(arr);//[1,2,5,8,11,15]

虽然上面能正确的排序数字,但是不能排序字符串,所以

修改排序二:

var arr = ['a', 1, 13, 'c', 'd','b', '13', 'bb'];
arr.sort(function (a, b) {
    if (typeof a === typeof b) {
        return a < b ? -1 : 1;
    }

    return typeof a < typeof b ? -1 : 1;
});
console.log(arr);//[1, 13, "13", "a", "b", "bb", "c", "d"]

排序对象,修改排序三:

var arr = [
    {name:'Joe',age:12},
    {name:'Moe',age:22},
    {name:'Joe',age:21},
    {name:'Shemp',age:29},
    {name:'Larry',age:22},
    {name:'Curly',age:30}
]

var by = function(key){
    return function(o,p){
        if(o && p && typeof o === 'object' && typeof p === 'object'){
            var a = o[key];
            var b = p[key];

            if(a === b){
                return 0;
            }

            if(typeof a === typeof b){
                return a < b ? -1 : 1;
            }

            return typeof a < typeof b ? -1 : 1;
        }else{
            throw {
                name:'Error',
                massage:'Expected an object when sorting by'+name
            }
        }
    }
};

正则表达式

1、创建方式

第一种方式:直接创建

var reg = /^\w{3,8}$/g;

正则表达式标识

标识 含义
g 全局的
i 忽略字符大小写
m 多行

第二种方式:RegExp对象

 var reg = new RegExp("^\\w\{3,8\}$");

RegExp对象的属性

属性 用法
global 如果标识 g 被使用,值为true
ignoreCase 如果标识i被使用,值为true
lastIndex 下一次exec匹配开始的索引 ,初始值为0
multiline 如果标识m被使用,值为true
source 正则表达式源码文本

2、正则表达式分支

var str = "into";
str.match(/in|int/); //匹配in,而不是int

3、正则表达式因子

定义:一个表达式因子可以是一个字符、一个有圆括号包围的组、一个字符类、或者是一个转义序列;

4、正则表达式转义

\ / [ ] ( ) { } ? + * | . ^ $ 都需要用一个 \ 前缀来进行转义

注意:\前缀不能使字母或数字字面化。

一个未被转义的 . 会匹配除行结束符以外的任何字符;

一个未转义 ^ 会匹配文本的开始,当指定了m 标识时,也能匹配行结束符;

一个未转义的 $ 将匹配文本的结束,当指定了 m 标识时,也能匹配行结束符;

\f 换页符
\n 换行符
\r 回车符
\t 制表符
\u Unicode字符的十六进制常量
\d 等于[0-9],匹配数字
\D 等于[^0-9],匹配非数字
\s 等于[\f\n\r\t\u00B\u0020\u00A0\u2028\u2029] 这是Unicode空白符的一个不完全子集
\S 等于[^\f\n\r\t\u00B\u0020\u00A0\u2028\u2029]
\w 等于 [0-9A-Z_a-z]
\W 等于[^0-9A-Z_a-z]
\b 被指定为一个字边界标识,方便用于对文本的字边界进行匹配
\1 指向分组1所捕获到的文本的一个引用
\2 指向分组2的引用
\3 指向分组3的引用

5、正则表达式分组

捕获型

一个捕获型分组是一个被包围在圆括号的正则表达式分支。任何匹配这个分组的字符都会被捕获。

非捕获型

非捕获型分组有一个(?: 前缀,非捕获型分组仅做简单的匹配,并不会捕获所匹配的文本。

向前正向匹配

向前正向匹配分组有一个(?= 前缀;类似于非捕获型分组,但在这个组匹配后,文本会倒回到它开始的地方。

向前负向匹配

向前负向匹配分组有一个 (?! 前缀

6、正则表示式量词

正则表达式因子可以用一个正则表达式量词后缀来决定这个因子应该被匹配的次数。它包围在一对花括号中的一个数组表示这个因子应该被匹配的次数;

/www/  ==  /w{3}/
{3,6}表示匹配3到6次
{3,}表示匹配至少3次
? 等同于{0,1} 匹配0到1次
* 等同于{0,} 匹配至少0次
+ 等同于{1,} 匹配至少1次

毒瘤

1、全局变量

定义全局变量的三种方法:

var foo = value;

window.foo = value;

foo = value;

弊端:全局变量使得在通一个程序中运行独立的子程序变得更难。

2、作用域

弊端:除了函数,javascript没有块级作用域;

3、自动插入分号

4、保留字

弊端:不能用来命名变量火参数。

5、Unicode

弊端:JavaScript的字符是16位,覆盖原有的65536个字符;剩下的百万字符的每一个都可以用一对字符来表示,Unicode把一对字符视为一个单一的字符,而javascript认为一对字符是两个不同的字符;

6、typeof

弊端:不能识别'null' 和数组 ,返回 'object';

7、parseInt

弊端:遇到非数字时会停止解析,所以parseInt('16')和parseInt('16 aaa')是相同结果;如果该字符串第一个字符是0,那么该字符会基于八进制,而不是十进制求值;

8、浮点数

弊端:二进制的浮点数不能正确地处理十进制的小数,因此0.1+0.2不等于0.3;因为javascript遵循的是二进制浮点数算术标准;

9、NaN

function isNumber(v){
    return typeof v === 'number' && isFinite(v);
 }

10、伪数组

javascript没有真正的数组;

弊端:typeof运算符不能辨别数组和对象

11、对象

弊端:JavaScript的对象永远不会是真的空对象,因为他们可以从原型链中取得成员属性;

JSON

1、定义:JavsScript对象表示法的简写,是一种轻量级的数据交换格式;

2、值的类型:对象、数组、字符串、数字、布尔值、特殊值null;

3、JSONd对象:是一个容纳“名/值”对的无序集合;名字可以是任何字符串,值可以使任何类型的JSON值。

4、JSON数组:是一个值的有序序列;值可以是任何类型的JSON值;

5、JSON字符串:被包围在一对双引号之间;

6、JSON数字:与JavaScript的数字类似,不循序首位为0;

上一篇:luoguP3369[模板]普通平衡树(Treap/SBT) 题解


下一篇:普通平衡树Treap(含旋转)学习笔记