短小精悍的javascript基础知识点

注:本文所有知识点总结或摘抄自廖雪峰javascript教程,点击查看更详细的讲解

1.javascript简介

  1. ECMAScript是一种语言标准,而JavaScript是网景公司对ECMAScript标准的一种实现。可以说javascript语言的标准是ECMAScript

2. 入门基础

  1. 在编写JavaScript代码时,经常需要在Console运行测试代码,常用console.log()
  2. 对于复杂的层级嵌套,需要把部分代码抽出来,作为函数调用,以减少代码的复杂程度。
  3. JavaScript严格区分大小写,如果弄错了大小写,程序将报错或者运行不正常。
  4. JavaScript不区分整数和浮点数,统一用Number表示。
  5. JavaScript有两种比较运算符:
    第一种是==比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果;
    第二种是===比较,它不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再比较。
  6. NaN这个特殊的Number与所有其他值都不相等,包括它自己:
NaN === NaN; // false

唯一能判断NaN的方法是通过isNaN()函数:

isNaN(NaN); // true

面试题中经常出现null undefined NaN相关知识点。

  1. 要比较两个浮点数是否相等,只能计算它们之差的绝对值,看是否小于某个阈值:
Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true
1 / 3 === (1 - 2 / 3); // false
  1. null表示一个“空”的值,它和0以及空字符串' '不同,0是一个数值,''表示长度为0的字符串,而null表示“空”。还有一个和null类似的undefined,它表示“未定义”。
  2. 数组的元素可以通过索引来访问,索引的起始值为0。
  3. 对象是一组由键(字符串类型)-值(任意数据类型)组成的无序集合,每个键又称为对象的属性。
  4. 申明一个变量用var语句,变量名是大小写英文、数字、$和_的组合,不能用数字开头,不能是关键字。
  5. 变量本身的数据类型不固定的语言称之为动态语言,与之对应的是静态语言。
  6. 变量没有通过var申明就被使用,那么该变量就自动被申明为全局变量。特别需要注意i的声明。
  7. 启用strict模式的方法是在JavaScript代码的第一行写上:
'use strict';
  1. ES6新增了一种模板字符串代替加号:
var name = '小明';
var age = 20;
var message = `你好, ${name}, 你今年${age}岁了!`;
alert(message);
  1. 常用的操作字符串方法
    调用这些方法本身不会改变原有字符串的内容,而是返回一个新字符串。
  • toUpperCase()把一个字符串全部变为大写;
  • toLowerCase()把一个字符串全部变为小写;
  • indexOf()会搜索指定字符串出现的位置;
var s = 'hello, world';
s.indexOf('world'); // 返回7
s.indexOf('World'); // 没有找到指定的子串,返回-1
  • substring()返回指定索引区间的子串。
var s = 'hello, world'
s.substring(0, 5); // 从索引0开始到5(不包括5),返回'hello'
s.substring(7); // 从索引7开始到结束,返回'world'
  1. 如果通过索引给数组赋值时,索引超过了范围,会引起数据大小的变化:
var arr = [1, 2, 3];
arr[5] = 'x';
arr; // arr变为[1, 2, 3, undefined, undefined, 'x']
  1. 常用的操作数组的方法
  • indexOf()搜索一个指定的元素的位置;
var arr = [10, 20, '30', 'xyz'];
arr.indexOf(10); // 元素10的索引为0
  • slice()截取Array的部分元素,然后返回一个新的Array
var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 从索引0开始,到索引3结束,但不包括索引3: ['A', 'B', 'C']

不给slice()传递任何参数来复制一个Array

  • push()Array的末尾添加若干元素;
  • pop()则把Array的最后一个元素删除掉;
  • unshift()Array的头部添加若干元素;
  • shift()则把Array的第一个元素删除掉;
  • sort()会直接修改当前Array的元素位置,对当前Array进行排序;
  • reverse()把整个Array的元素给掉个个,也就是反转;
  • splice()方法是修改Array的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素:
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不删除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
  • concat()方法把当前的Array和另一个Array连接起来,并返回一个新的Array
  • join()方法把当前Array的每个元素都用指定的字符串连接起来,然后返回连接后的字符串:
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'

如果Array的元素不是字符串,将自动转换为字符串后再连接。

  1. JavaScript中能用.的地方就能用[ ]代替:
xiaohong['name']; // '小红'
xiaohong.name; // '小红'
  1. JavaScript规定,访问不存在的属性不报错,而是返回undefined
var xiaoming = {
    name: '小明'
};
xiaoming.age; // undefined
  1. 检测xiaoming是否拥有某一属性:
  • 可以用in操作符(无法确定属性来自本身还是来自继承)
'name' in xiaoming; // true
'grade' in xiaoming; // false
  • 可以用hasOwnProperty()方法(判断一个属性是否自身拥有)
var xiaoming = {
    name: '小明'
};
xiaoming.hasOwnProperty('name'); // true
xiaoming.hasOwnProperty('toString'); // false
  1. if...else...语句的执行特点是二选一,在多个if...else...语句中,如果某个条件成立,则后续就不再继续判断了。
  2. JavaScript把nullundefined0NaN和空字符串''视为false,其他值一概视为true
  3. for循环的一个变体是for ... in循环,它可以把一个对象的所有属性依次循环出来:
var o = {
        name: 'Jack',
        age: 20,
        city: 'Beijing'
};
for (var key in o) {
        alert(key); // 'name', 'age', 'city'
}
  1. 由于Array也是对象,而它的每个元素的索引被视为对象的属性,因此,for ... in循环可以直接循环出Array的索引:
var a = ['A', 'B', 'C'];
for (var i in a) {
        alert(i); // '0', '1', '2'
        alert(a[i]); // 'A', 'B', 'C'
}

for ... inArray的循环得到的是String而不是Number

  1. Map是一组键(key)值(value)对的结构,具有极快的查找速度。
    假设要根据同学的名字查找对应的成绩,如果用Array实现,需要两个Array
var names = ['Michael', 'Bob', 'Tracy'];
var scores = [95, 75, 85];

给定一个名字,要查找对应的成绩,就先要在names中找到对应的位置,再从scores取出对应的成绩,Array越长,耗时越长。
如果用Map实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。用JavaScript写一个Map如下:

var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95
  1. SetMap类似,也是一组key的集合,但不存储value
  2. MapSet是ES6标准新增的数据类型。
  3. 遍历Array可以采用下标循环,遍历MapSet就无法使用下标。ES6标准引入了新的iterable类型,ArrayMapSet都属于iterable类型。
  4. iterable类型的集合可以通过新的for ... of循环来遍历。for ... of循环和for ... in循环有何区别?
  5. 函数体内部的语句执行到return时,函数就执行完毕,并将结果返回。如果没有return,返回结果是undefined
  6. arguments只在函数内部起作用,指向当前函数的调用者传入的所有参数。利用其可以获得调用者传入的所有参数,最常用于判断传入参数的个数。
  7. 小心return语句(JavaScript引擎有一个在行末自动添加分号的机制,这可能让你栽到return语句的一个大坑):
function foo() {
      return { name: 'foo' };
}
foo(); // { name: 'foo' }
function foo() {
      return
        { name: 'foo' };
}
foo(); // undefined
  1. 定义一个计算圆面积的函数square(),它有两个参数:
    • r: 表示圆的半径;
    • pi: 表示π的值,如果不传,则默认3.14。
      一般写法:
function square(r, pi) {
        var r,pi;
        if(pi) {
          return pi*r*r;
        }
        else {
           return 3.14*r*r;
        }

经典写法:

function square(r, pi) {
        var r,pi;
        r = (r || 0) > 0 ? r : 0;
        pi = pi || 3.14;
        return pi*r*r;
 }
  1. var申明的变量是有作用域的:
  • 变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量;
  • 不同函数内部的同名变量互相独立,互不影响;
  • 嵌套函数时,内部函数可以访问外部函数定义的变量,反过来则不行;
  • 内部函数定义了与外部函数重名的变量,则内部函数的变量将“屏蔽”外部函数的变量。
    (这说明JavaScript的函数在查找变量时从自身函数定义开始,从“内”向“外”查找。)
  1. 函数会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部,但不会提升变量的赋值:
function foo() {
        var x = 'Hello, ' + y;
        alert(x);
        var y = 'Bob';
}
foo();   //Hello, undefined
  • 不报错:变量y在稍后申明了。
  • 显示Hello, undefined:说明变量y的值为undefined。JavaScript引擎自动提升了变量y的声明,但不会提升变量y的赋值。
  1. 全局作用域的变量实际上被绑定到window的一个属性。
    直接访问全局变量a和访问window.a是完全一样的。
  2. let替代var可以申明一个块级作用域的变量。
  3. ES6标准引入了新的关键字const来定义常量,constlet都具有块级作用域。
  4. 通常用全部大写的变量来表示“这是一个常量,不要修改它的值”:const PI = 3.14;
  5. 绑定到对象上的函数称为方法,和普通函数没啥区别。
  6. 在一个方法内部,this是一个特殊变量,它始终指向当前对象。
    这里有坑:详情移步 廖雪峰-方法
function getAge() {
        var y = new Date().getFullYear();
        return y - this.birth;
}
var xiaoming = {
        name: '小明',
        birth: 1990,
        age: getAge
};
xiaoming.age(); // 25, 正常结果
getAge(); // NaN
  • 以对象的方法形式调用,比如xiaoming.age(),该函数的this指向被调用的对象,也就是xiaoming
  • 如果单独调用函数,比如getAge(),此时,该函数的this指向全局对象,也就是window
  • 即使把xiaoming.age()先给函数,再调用也不行。
var fn = xiaoming.age; // 先拿到xiaoming的age函数
fn(); // NaN
  • ECMA决定,在strict模式下让函数的this指向undefined
  • 在方法函数内部定义的函数内this指向undefined
  1. 要指定函数的this指向哪个对象,可以用函数本身的apply方法,它接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是Array,表示函数本身的参数。
  2. 另一个与apply()类似的方法是call(),唯一区别是:
  • apply()把参数打包成Array再传入;
  • call()把参数按顺序传入
  1. js调用函数时加括号与不加括号的区别:
    函数名其实就是指向函数体的指针 ,
  • 不加括号, 可以认为是查看该函数的完整信息;
  • 加括号 表示立即调用(执行)这个函数里面的代码(花括号部分的代码);
  • 不加括号传参,相当于传入函数整体 ;
  • 加括号传参,相当于将函数的返回值作为参数。
  1. Arraymap()方法
function pow(x) {
        return x * x;
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
  1. reduce()把结果继续和序列的下一个元素做累积计算:
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
        return x + y;
}); // 25
  1. filter()map()类似也接收一个函数,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。
var arr = [1, 2, 4, 5, 6, 9, 10, 15];
var r = arr.filter(function (x) {
        return x % 2 !== 0;
});
r; // [1, 5, 9, 15]
  1. sort()方法也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。
var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
        if (x < y) {
                return -1;
    }
        if (x > y) {
                return 1;
    }
        return 0;
}); // [1, 2, 10, 20]
  1. 闭包,我不敢说太多,因为自己也没有明白得太清楚,但是我感觉这几篇文章值得看。javascript深入理解js闭包
    深入理解javascript原型和闭包(完结)
  2. 箭头函数相当于匿名函数,并且简化了函数定义,两种格式:
  • 简化格式
    • 单参数
x => x * x

上面的箭头函数相当于:

function (x) {
        return x * x;
}
 * 多参数
(x, y) => x * x + y * y
 * 无参数
() => 3.14
  • 标准格式
x => {
        if (x > 0) {
            return x * x;
        }
        else {
            return - x * x;
        }
}
  1. 不要使用·new Number()·、·new Boolean()·、·new String()·创建包装对象;

  2. parseInt()parseFloat()来转换任意类型到number

  3. String()来转换任意类型到string,或者直接调用某个对象的toString()方法;

  4. 通常不必把任意类型转换为boolean再判断,因为可以直接写if (myVar) {...}

  5. typeof操作符可以判断出numberbooleanstringfunctionundefined

  6. 判断Array要使用Array.isArray(arr)

  7. 判断null请使用myVar === null

  8. 判断某个全局变量是否存在用typeof window.myVar === 'undefined'

  9. 函数内部判断某个变量是否存在用typeof myVar === 'undefined'

  10. Date对象用来表示日期和时间。要获取系统当前时间,用:

var now = new Date();
now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
now.getFullYear(); // 2015, 年份
now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
now.getDate(); // 24, 表示24号
now.getDay(); // 3, 表示星期三
now.getHours(); // 19, 24小时制
now.getMinutes(); // 49, 分钟
now.getSeconds(); // 22, 秒
now.getMilliseconds(); // 875, 毫秒数
now.getTime(); // 1435146562875, 以number形式表示的时间戳
  1. 正则表达式的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
  2. js正则表达式基本语法(精粹)
  3. 对象的两个基本概念:
  • 类:类是对象的类型模板,例如,定义Student类来表示学生,类本身是一种类型,Student表示学生类型,但不表示任何具体的某个学生;
  • 实例:实例是根据类创建的对象,例如,根据Student类可以创建出xiaoming、xiaohong、xiaojun等多个实例,每个实例表示一个具体的学生,他们全都属于Student类型。
    JavaScript不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程。
  1. window对象不但充当全局作用域,而且表示浏览器窗口。有innerWidthinnerHeight属性,可以获取浏览器窗口的内部宽度和高度。内部宽高是指除去菜单栏、工具栏、边框等占位元素后,用于显示网页的净宽高。outerWidthouterHeight属性,可以获取浏览器窗口的整个宽高。
  2. DOM是一个树形结构。操作一个DOM节点实际上就是这么几个操作:
  • 更新:更新该DOM节点的内容;
    • innerHTML可以修改一个DOM节点的文本内容,还可以通过HTML片段修改DOM节点内部的子树;
    • innerTexttextContent修改一个DOM节点的文本内容,无法设置任何HTML标签。innerText不返回隐藏元素的文本,而textContent返回所有文本。
  • 遍历:遍历该DOM节点下的子节点;
  • 添加:在该DOM节点下新增一个子节点;
    • 如果这个DOM节点是空的,直接使用innerHTML = '<span>child</span>',不是空的,那就不能这么做,因为innerHTML会直接替换掉原来的所有子节点;
    • 使用appendChild,把一个子节点添加到父节点的最后一个子节点;
      *使用insertBefore,把子节点插入到指定的位置。
  • 删除:将该节点从HTML中删除。
    • 要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的removeChild把自己删掉

感谢各位阅读,欢迎指正错误!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,290评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,399评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,021评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,034评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,412评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,651评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,902评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,605评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,339评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,586评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,076评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,400评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,060评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,851评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,685评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,595评论 2 270

推荐阅读更多精彩内容

  • 原文: https://github.com/ecomfe/spec/blob/master/javascript...
    zock阅读 3,343评论 2 36
  • JS基础讲解 JavaScript组成ECMAScript:解释器、翻译DOM:Document Object M...
    FConfidence阅读 546评论 0 1
  • 1. 本文是在学习廖雪峰先生的JavaScrip教程 后的归纳 2. 本文是第一次采用markdown进行书写 J...
    ting723阅读 721评论 0 5
  • 忽然念及四月 几度风吹树 吹落庭前 一枝暖 忽然念及海棠 这简单而平凡的处事方式 自己绽放了 另一朵 才不会孤单
    小麦iii阅读 306评论 2 15
  • 元气是什么? 元气是出生那天爹妈给的那个“气数”。 元气是人的先天“定量”。 元气能不能增加呢? 不能。 怎么才能...
    金刚葫芦GF阅读 484评论 0 6