JavaScript---Web学习总结

1 何为JavaScript

  • JavaScript 是一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。
    现在JavaScript再也不是简单的脚本语言了,无论前端还是后台,JavaScript都有良好的表现!
  • 基础的JavaScript学习可以参见:
    W3school-领先的Web技术教程
    W3C菜鸟教程
  • 运行JavaScript的方式:
    可以直接在浏览器的控制台编写运行
    也可以编写一个独立的js文件,然后在Html文件中引入
    也可以用编辑软件如Webstrom或VSCode编写独立的js文件,由安装好的Node.js解释执行运行。

2 基本语法

2.1 JavaScript 对大小写敏感

所有 JavaScript 标识符对大小写敏感。
如:变量 Namename,是两个不同的变量。

2.2 标识符

  • 标识符是名称,指变量、函数、属性的名字,或者函数的参数。
  • 在 JavaScript 中,首字符必须是字母下划线(-)美元符号($)
    连串的字符可以是字母数字下划线美元符号
  • 按照惯例,ECMAScript(European Computer Manufacturers Association) 标识符采用 驼峰大小写格式,也就是第一个字母小写,剩下的每个单词的首字母大写,如 firstName, lastName, masterCard, interCity
  • 注意:数值不可以作为首字符。这样,JavaScript 就能轻松区分标识符和数值。

2.3 注释

JavaScript 注释用于解释 JavaScript 代码,增强其可读性。
JavaScript 注释也可以用于在测试替代代码时阻止执行。

  • 单行注释
    单行注释以 // 开头。
    任何位于 // 与行末之间的文本都会被 JavaScript 忽略(不会执行)。
  • 多行注释
    多行注释以 /* 开头,以 */ 结尾。
    任何位于 /**/ 之间的文本都会被 JavaScript 忽略。
    注意:使用单行注释最为常见。
  • 使用注释来阻止执行
    使用注释来防止代码执行很适合代码测试。
    在代码行之前添加 // 会把可执行的代码行更改为注释。

2.4 语句

在 HTML 中,JavaScript 语句是由 web 浏览器“执行”的“指令”。

  • 构成
    JavaScript 语句由以下构成:
    值、运算符、表达式、关键词和注释。
  • 分号 ;
    分号分隔 JavaScript 语句。
    在每条可执行的语句之后添加分号,以分号结束语句不是必需的。

2.5 关键字/保留字

在 JavaScript 中,一些标识符是保留关键字,不能用作变量名或函数名。

  • 常见的关键字/保留字
breakdoinstanceoftypeofcase
elsenewvarcatchfinally
voidcontinueforswitchwhile
debuggerfunctionthiswithdefault
ifthrowdeleteintry

详细内容可见:JavaScript 保留词

2.6 变量

JavaScript 变量是存储数据值的容器。

  • ECMAScript 的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。换句话说,每个变量仅仅是一个用于保存值的占位符而已。
  • 定义变量
    定义变量时要使用 var 操作符
    注意:即用 var 操作符定义的变量将成为定义该变量的作用域中的局部变量。也就是说,如果在函数中使用 var 定义一个变量,那么这个变量在函数退出后就会被销毁。
  • 重复声明 JavaScript 变量
    如果再次声明某个 JavaScript 变量,将不会丢它的值。
  • Value = undefined
    在计算机程序中,被声明的变量经常是不带值的。值可以是需被计算的内容,或是之后被提供的数据,比如数据输入。
    不带有值的变量,它的值将是 undefined
    例如:
    在这里插入图片描述
    在这里插入图片描述
  • 一条语句,多个变量
    可以在一条语句中声明许多变量。
    var 作为语句的开头,并以逗号分隔变量。
    例如:
    在这里插入图片描述
    在这里插入图片描述

2.7 操作符

  • 一元操作符
运算符描述
++递加
递减

一元运算符,只有一个操作数
可以写在变量前和变量后面,位置不同可能导致程序运行结果不同

  • 布尔操作符(逻辑运算符)
    &&:逻辑与
    ||:逻辑或
    !:逻辑非
    • 注意:&&和||都属于 短路操作!
    • 除下列值为假外其余皆为真: false、null、undefined、‘’、0、NaN
  • 算术操作符
运算符描述
+加法
-减法
*乘法
/除法
%取模(余数)
++递加
递减
  • 关系操作符
运算符描述
==等于
===等值等型
!=不相等
!==不等值或不等型
>大于
<小于
>=大于或等于
<=小于或等于

注意: ===称为全等(值和类型相等)

  • 条件(问号)操作符
    条件(问号)操作符? :
    能有效的简洁代码
  • 赋值操作符
    常见赋值操作符: = += -+ *= /= %=

2.8 语句

  • JavaScript 代码块
    JavaScript 语句可以用花括号({...})组合在代码块中。
    代码块的作用是定义一同执行的语句。
  • 关键词
    大部分与常见的c语言关键词类似:if do-while while for for-in for-of break continue switch
    其中,需要注意for-offorEach能简洁的遍历集合中的元素。
  1. for…in
    作用:
    for…in 语句用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作),其所遍历的为对象的属性名(键),而非属性值。
    语法:
for (variable index in object){
    //...
}
  1. for…of
    作用:
    for…of语法是ES6新引入的语法,for…of语法用于遍历可迭代(iterable)对象,js中的可迭代对象包括字符串String、数组Array、集合Set、字典Map、arguments 对象、DOM NodeList 对象等等,for…of语法用于遍历这些对象本身的元素。
    语法:
for (variable element of iterable){    
    //...
}
  1. forEach
    作用:
    forEach作用于数组对象,用于遍历数组对象的每一个元素,并对每一个元素执行回调(callback)函数。
    语法:
ArrayObject.forEach(callback(currentValue, index, arr), thisValue))
//其中currentValue为遍历时数组中每次进行输入到回调函数的当前元素,为必需参数;
//index为当前元素的索引值,为可选参数;
//array为当前元素所属的数组对象,为可选参数。
//thisValue为传递给回调函数的"this"值,可选,如果这个参数为空,则"undefined"则会传递给"this"值。

2.9 函数(function)

JavaScript 函数是被设计为执行特定任务的代码块。
JavaScript 函数会在某代码调用它时被执行。

  • 函数语法
function name(参数 1, 参数 2, 参数 3) {
    要执行的代码
}
//在函数中,参数是局部变量
  • 函数调用
    函数中的代码将在其他代码调用该函数时执行:
    • 当事件发生时(当用户点击按钮时)
    • 当 JavaScript 代码调用时
    • 自动的(自调用)

调用栈
JS引擎在调用一个函数前,需要把函数所在的环境push到一个数组里,这个数组叫做调用栈,等函数执行完了,就会把环境弹出(pop)出来,然后return到之前的环境,继续执行后续代码

  • 函数返回
    当 JavaScript 到达 return 语句,函数将停止执行。
    如果函数被某条语句调用,JavaScript 将在调用语句之后“返回”执行代码。
    • ECMAScript 中的函数在定义时不必指定是否返回值
    • ECMAScript 函数不介意传递进来多少个参数,传递的参数与定义时的个数可以不一致。
      原因: ECMAScript 中的参数在内部是用一个数组来表示的。函数接收到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任何元素,无所谓;如果包含多个元素,也没有问题。
    • ECMAScript中定义了两个名字相同的函数,则该名字只属于后定义的函数

2.10 对象Object

常将数据和方法封装在对象中。
创建对象有如下两种方式,我们常用第二种。


//方式一new
var person = new Object();//生成空对象
person.name = 'Elon Musk';//设置对象的属性
person.age = 46;
person.job = 'SpaceX Rocket';
person.sayName = function(){    //设置对象的方法/函数,注意此处
    console.log(this.name);
};
//方式二字面量
var person = {
    name: 'Lary Page',
    age: 47,
    job: 'Software Engineer',
    sayName: function(){        //注意此处
        console.log(this.name);
    }
};
console.log(person.job);
person.sayName();

注意:空格和折行都是允许的。对象定义可横跨多

之后,进一步改进简化:

var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"};
function createPerson(name, age, job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        console.log(this.name);
    };
    return o;
}
var person1 = createPerson('Steve Jobs',56 , 'Inventor');
var person2 = createPerson('Linus Torvalds', 49, 'Software Engineer');
var person2 = createPerson('Julian Assange', 47, 'Ethical Hacker');
  • this 关键词
    在函数定义中,this 引用该函数的“拥有者”。
    在上面的例子中,this 指的是“拥有” fullName 函数的 person 对象。
    换言之,this.firstName 的意思是 this 对象的 firstName 属性。

2.11 数组Array

JavaScript 数组用于在单一变量中存储多个值。

  • 与其他语言不同的是,ECMAScript 数组的每一项 可以保存任何类型的数据(不建议!)
  • ECMAScript 数组的大小是可以动态调整的,即可以随着数据的添加自动增长以容纳新增数据。

创建数组

  • 使用 JavaScript 关键词 new
  • 使用数组文本是创建 JavaScript 数组最简单的方法。(通常使用)
//方式一new
var cars = new Array("Saab", "Volvo", "BMW");
//方式二字面量
var cars = ["Saab", "Volvo", "BMW"];
//访问数组元素
var name = cars[0];
//修改数组元素
cars[0] = "Opel";
//访问完整数组
var cars = ["Saab", "Volvo", "BMW"];
document.getElementById("demo").innerHTML = cars; 
// 创建一个空数组
var names = [];
 // 将一组值转换成数组
var arr = Array.of(element0, element1, ..., elementn) 

var hyBird = [1, 2, 'haha', {firstName: 'Yong', lastName: 'Wang'}]; //不推荐!
console.log(hyBird[3].firstName);

常用的数组方法

  • 元素联合
var colors = ['red', 'green', 'blue'];
console.log(colors.join(',')); //red,green,blue
console.log(colors.join('||')); //red||green||blue
  • 堆栈方法

栈是一种 LIFO(Last-In-First-Out,后进先出)的数据结构,也就是最新添加的项最早被移除。而栈中项的插入(叫做推入)和移除(叫做弹出),只发生在一个位置——栈的顶部。

ECMAScript 为数组专门提供了 push()pop() 方法,以便实现类似栈的行为。
push()
可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度

let arr = [1, 2, 3];
arr.push(4);

console.log(arr); // [ 1, 2, 3, 4 ]
console.log(arr.length); // 4

pop()
从数组末尾移除最后一项,减少数组的length值,然后返回移除的项

let arr = [1, 2, 3];
let delVal = arr.pop();

console.log(arr); // [ 1, 2]
console.log(delVal); // 3
  • 队列方法
    栈数据结构的访问规则是 LIFO(后进先出),而队列数据结构的访问规则是 FIFO(First-In-First-Out,先进先出)。队列在列表的末端添加项,从列表的前端移除项。
    由于 push() 是向数组末端添加项的方法,因此要模拟队列只需一个从数组前端取得项的方法。实现这一操作的数组方法就是 shift() ,它能够移除数组中的第一个项并返回该项,同时将数组长度减1。

shift()
移除数组中的第一个项并返回该项,同时将数组长度减1

let arr = [1, 2, 3];
let delVal = arr.shift();
console.log(delVal); // 1
console.log(arr); // [ 2, 3 ]
console.log(arr.length); // 2

unshift()
在数组前端添加任意个项并返回新数组的长度

let arr = [1, 2, 3];
let arrLength = arr.unshift(0);

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

总结: pushpop操作在数组末,而 unshiftshift操作在数组头;pushunshift压入,而popshift弹出。

  • 反转数组项
var values = [1, 2, 3, 4, 5];
values.reverse();
console.log(values); //5,4,3,2,1
  • 链接方法
var colors1 = ['red', 'green', 'blue'];
var colors2 = ['yellow', 'black'];
console.log(colors1.concat(colors2));
console.log(colors2.concat(colors1));
console.log(colors2.concat('brown'));
console.log(color2)//注意:concat返回一个新数组,原数组没改变
  • 分片方法
    slice()
    它能够基于当前数组中的一或多个项创建一个新数组。
  • slice() 方法可以接受一或两个参数,即要返回项的起始和结束位置
  • 在只有一个参数的情况下,slice() 方法返回从该参数指定位置开始到当前数组末尾的所有项。
  • 如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。
  • 注意,slice() 方法不会影响原始数组
let arr = [1, 2, 3, 4];

let newArr = arr.slice(1, 2);
console.log(newArr); // [ 2 ]

let newArr2 = arr.slice(1);
console.log(newArr2); // [ 2, 3, 4 ]
  • splice方法
    注意: splice() 方法直接更改原始数组。
    splice() 方法对数组如下3种操作:
    • 删除:
      可以删除任意数量的项,只需指定2个参数:要删除的第一项的位置和要删除的项数。
      例如,splice(0,2)会删除数组中的前两项。
    • 插入
      可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、0(要删除的项数) 和要插入的项。如果要插入多个项,可以再传入第四、第五,以至任意多个项。
      例如, splice(2,0,'red','green') 会从当前数组的位置 2 开始插入字符串 'red''green'
    • 替换
      可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定3个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。
      例如,splice (2,1,“red”,“green”)会删除当前数组位置2的项,然后再从位置2开始插入字符串"red""green"

2.12 链式语法

javascript的链式编程的核心就是 return this;
链式语法只需要让每个函数返回 this代表包含该函数的对象,这样其他函数就可以立即被调用。

//链式语法
var bird = {//定义对象字面量
  catapult: function() {
    console.log( 'Yippeeeeee!' );
    return this;//返回bird对象自身
  },
  destroy: function() {
    console.log( "That'll teach you... you dirty pig!" );
    return this;
  }
};
bird.catapult().destroy();//destroy()后还可以再链接吗?

2.13 闭包

  • 闭包是Closure,这是静态语言所不具有的一个新特性。闭包就是:函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。
    闭包就是就是函数的“堆栈”在函数返回后并不释放,也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配。

当在一个函数内定义另外一个函数就会产生闭包。

function greeting(name) {
    var text = 'Hello ' + name; // local variable
    // 每次调用时,产生闭包,并返回内部函数对象给调用者
    return function() { console.log(text); }//注意该函数无名称,称为匿名函数
}
var sayHello = greeting('Closure');//调用greeting()返回了什么?
sayHello();  // 注意此处的使用方法。通过闭包访问到了局部变量text

上述代码的执行结果是:Hello Closure

因为sayHello指向了greeting函数对象,sayHello()则对其进行调用,greeting函数执行完毕后将返回greeting函数内定义的匿名函数对象,而该匿名函数仍然可以访问到了定义在greeting之内的局部变量text。
注意此时我们已从greeting函数中退出了(但请留意,也只有该内部匿名函数能访问,其它任何代码都不能访问)

var scope = 'global scope';	//全局变量
function checkScope(){
    var scope = 'local scope';	//局部变量
    function f(){
        return scope;
    }
    return f;
}
checkScope()();		//注意此处的使用方法。返回值为local scope而非global scope
  • 闭包的几种表现形式
  1. 返回一个函数
var a  = 1;
function foo(){
  var a = 2;
  // 这就是闭包
  return function(){
    console.log(a);
  }
}
var bar = foo();
// 输出2,而不是1
bar();
  1. 作为函数参数传递
    无论通过何种手段将内部函数传递到它所在词法作用域之外,它都会持有对原始作用域的引用,无论在何处执行这个函数,都会产生闭包。
var a = 1;
function foo(){
  var a = 2;
  function baz(){
    console.log(a);
  }
  bar(baz);
}
function bar(fn){
  // 这就是闭包
  fn();
}
// 输出2,而不是1
foo();
  1. 回调函数
    在定时器、事件监听、Ajax请求、跨窗口通信、Web Workers或者任何异步中,只要使用了回调函数,实际上就是在使用闭包。
// 定时器
setTimeout(function timeHandler(){
  console.log('timer');
}100)

// 事件监听
$('#container').click(function(){
  console.log('DOM Listener');
})
  1. 非典型闭包IIFE(立即执行函数表达式)
    IIFE(立即执行函数表达式)并不是一个典型的闭包,但它确实创建了一个闭包。
var a = 2;
(function IIFE(){
  // 输出2
  console.log(a);
})();

3 参考资料

  1. JavaScript中for…in,for…of,forEach的区别
  2. JavaScript数组方法大全
  3. JavaScript闭包
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值