MDN Web 文档学习笔记——JavaScript

Posted by Waynerv on

category: 前端

Tags: JavaScript

JavaScript — 用户端动态脚本

JavaScript第一步

什么是JavaScript

  1. JavaScript是一种脚本语言,可以用来创建动态更新的内容,控制多媒体,制作图像动画
  2. 借助于应用程序接口(API),JavaScript能实现更强大的功能。API如文档对象模型API、地理位置API、画布API及第三方API
  3. 通过DOM动态修改HTML和CSS来更新UI是JavaScript最普遍的用处。如果JavaScript在HTML和CSS就位之前加载运行,就会引发错误
  4. 每个浏览器标签页的代码运行环境是相对独立的以保障安全性
  5. 添加JavaScript:
    • 内部添加:在</body>标签前插入<script></script>元素
    • 外部引用:创建js文件并使用<script>src属性进行引用
    • 内联处理器:不要使用此操作,示例<button onclick="createParagraph()">点我呀</button>
  6. 注释:双斜杠后添加单行注释,在 /* 和 */ 之间添加多行注释

初次接触JavaScript

  1. 示例-猜数字游戏

调试代码错误

  1. 错误分类:语法错误逻辑错误
  2. 调试工具:浏览器开发者工具
  3. 常见错误:语句缺少分号;参数列表缺少冒号;属性ID缺少冒号;函数体末尾缺少花括号;字符串缺少闭口引号

变量

  1. 特点:存放的值可以改变,能够存储任何东西
  2. 变量不是数值本身,它们仅仅是一个用于存储数值的容器
  3. 使用变量需要先声明,也可在赋值的同时声明:var myName = 'Chris';
  4. 小写驼峰命名法:小写整个命名的第一个字母然后大写剩下单词的首字符
  5. 避免使用保留字
  6. JavaScript的布尔类型表示是true和false,不大写
  7. Array类似与Python中的列表,可通过下标索引
  8. Object概念类似于Python中的类实例,通过var dog = { name : 'Spot', breed : 'Dalmatian' };定义对象属性

数字和操作符

  1. JavaScript只有1个数值类型:Number,拥有整数、浮点数、双精度浮点数等十进制数
  2. 算数运算符:+,-,*,/,%,基本规则同Python
  3. 递增和递减运算符:加1或减1
  4. 赋值运算符:基本同Python
  5. 比较运算符:除===和!==外基本同Python

字符串

  1. 引号使用条件基本同Python
  2. 同样使用反斜杠\转义
  3. 连接字符串:使用+拼接字符串
  4. 字符串和数值拼接时,数值将被自动转换为字符串
  5. 使用.toString()方法将数值转换为字符串
  6. 使用Number()函数将字符串转换为数值(类似int())

字符串方法

  1. 获取字符串长度:length属性
  2. 通过下标索引子串:browserType[browserType.length-1];
  3. 在字符串中查找子串:browserType.indexOf('zilla');返回索引值或-1(不存在)
  4. 提取字符串子串:browserType.slice(0,3);,如果没有传入第二个参数,结束位置会在原始字符串的末尾
  5. 转换大小写:toLowerCase()和toUpperCase()方法
  6. 替换字符串:browserType = browserType.replace('old','new');

数组

  1. 创建数组(类似Python列表): var shopping = ['bread', 'milk', 'cheese', 'hummus', 'noodles']; shopping;
  2. 访问和修改组项:基本和Python相同
  3. 查找数组长度:sequence.length;,常见的数组遍历循环: var sequence = [1, 1, 2, 3, 5, 8, 13]; for (var i = 0; i < sequence.length; i++) { console.log(sequence[i]); }
  4. 分割字符串为数组:ar myArray = myData.split(',');
  5. 联结数组为字符串:var myNewString = myArray.join(',');
  6. 将数组转换为字符串的另一种方法是使用toString()方法: var dogNames = ["Rocket","Flash","Bella","Slugger"]; dogNames.toString(); //Rocket,Flash,Bella,Slugger
  7. 添加和删除数组项:
    • 在数组末尾添加或删除一个项目,使用push(item)pop()方法
    • 在数组开始处添加或删除一个项目,使用unshift(item)shift()方法

JavaScript基础要件

条件语句

if...else语句
  1. 基础语法(不一定需要else和第二个花括号): html if (condition) { code to run if condition is true } else { run some other code instead }
  2. 分支条件语句:else if等于Python中的elif
  3. 任何不是false, undefined, null, 0, NaN的值或一个空字符串('')在作为条件语句进行测试时实际返回true
  4. 逻辑运算符(可组合使用):
    • &&逻辑与,等于python中的and
    • ||逻辑或,等于python中的or
    • 逻辑非,等于python中的not
switch语句
  1. 基础语法(default语句非必需,用来处理未知情况):

    switch (expression) {
      case choice1: // 如果选择与表达式匹配,则运行下方代码
        run this code
        break;
    
      // include as many cases as you like
    
      default:
        actually, just run this code
    }
    
三元运算符
  1. 条件语句的简略形式: html ( condition ) ? if true run this code : or run this code instead

循环结构

  1. for循环基础语法: html for (initializer; exit-condition; final-expression) { // code to run }
  2. for循环常见实例:

    var cats = ['Bill', 'Jeff', 'Pete', 'Biggles', 'Jasmin'];
    var info = 'My cats are called ';
    var para = document.querySelector('p');
    
    for (var i = 0; i < cats.length; i++) {
      if (i === cats.length - 1) {
        info += 'and ' + cats[i] + '.';
      } else {
        info += cats[i] + ', ';
      }
    }
    
    para.textContent = info;
    
  3. 注意无限循环问题
  4. 使用break退出循环
  5. 使用continue跳过后续语句
  6. while循环基础语法:

    initializer
    while (exit-condition) {
      // code to run
    
      final-expression
    }
    
  7. do...while循环基础语法(先执行一次再检查条件):

    initializer
    do {
      // code to run
    
      final-expression
    } while (exit-condition)
    

函数

  1. 内置函数:大多数调用浏览器后台的函数的代码,是使用像C++这样更低级的系统语言编写的
  2. 内置浏览器函数并不是函数——它们是方法,内置浏览器功能(方法)和变量(称为属性)存储在结构化对象内
  3. 匿名函数通常用于运行负载的代码以响应事件触发(如点击按钮)-使用事件处理程序,常见示例:

    var myButton = document.querySelector('button');
    
    myButton.onclick = function() {
      alert('hello');
    }
    
  4. 数组join()函数的参数默认为逗号分隔符
  5. 所有函数的最外层被称为全局作用域。 在全局作用域内定义的值可以在任意地方访问。
  6. 函数作用域(同Python)

自定义函数

  1. onclick后应该接函数名称而不用加括号:btn.onclick = displayMessage;
  2. 如果要在点击事件里面绑定函数,不能直接使用displayMessage('Woo'),要把它放在一个匿名函数里面,不然函数会直接调用

函数返回值

  1. random()函数接受1个参数-1个整数,返回0到这个整数之间的随机数
  2. isNaN()函数测试num的值是否不是一个数字-如果不是数字,就返回true,否则返回false

事件

  1. 事件是在编程时系统内发生的动作或者发生的事情,系统会在事件出现的时候触发某种信号并且提供自动加载某种动作(如运行代码)的机制
  2. 事件触发时会运行的代码块即为事件处理器
  3. onclick是被用在这个情景下的事件处理器属性,将一些代码赋值给它时,只要事件触发代码就会运行。
  4. 请勿使用行内事件处理器
  5. addEventListener()和removeEventListener(),参数分别为事件处理器名称和要执行的代码块,可以方便的添加和清除处理器
  6. 使用addEventListener()的优势:可以删除事件处理程序代码;可以向同一类型的元素添加多个不同代码的监听器
  7. 事件对象:事件对象e的target属性始终是事件刚刚发生的元素的引用,可以使用任何名称作为事件对象,使用示例:

    var divs = document.querySelectorAll('div');
    
    for (var i = 0; i < divs.length; i++) {
      divs[i].onclick = function(e) {
        e.target.style.backgroundColor = bgChange();
      }
    }
    
  8. onsubmit事件处理器:表单被提交时触发;preventDefault()函数,停止表单提交
  9. 事件触发顺序:冒泡及捕获(默认情况下,所有事件处理程序都在冒泡阶段进行注册): !事件冒泡及捕获
  10. 在标准事件对象上调用stopPropagation()函数, 让当前事件处理程序可以运行但不会在冒泡链上扩散
  11. 事件委托:在父节点上设置事件监听器通过冒泡影响每个子节点,代替在每个子节点上设置监听器

评估

  1. JavaScript貌似不提供格式化字符串方法,大部分场景通过字符串与变量实现,也可以自定义格式化函数(传入参数替换占位符)

JavaScript对象介绍

JavaScript对象基础

  1. 对象语法(每一个名字/值对被逗号分隔开,并且名字和值之间由冒号分隔): html var objectName = { member1Name : member1Value, member2Name : member2Value, member3Name : member3Value }
  2. 传输一些有结构和关联的资料时常见的方式是使用字面量来创建一个对象
  3. 使用与Python类似的方式来访问对象的属性和方法,可以在对象内部嵌套另一个对象
  4. 除了.表示法还可以使用括号表示法:person.name.first等价于person['name']['first']
  5. 可以直接用以上方法访问,修改甚至创建对象成员\
  6. 点表示法只能接受字面量成员的名字(实质为字符串).括号表示法可以接受变量作为名字
  7. "this"含义类似Python中的"self",指代当前实例对象(代码运行时所在的对象)
  8. 每个页面在加载完毕后,会有一个Document的实例被创建,叫做document,它代表了整个页面的结构,内容和一些功能,比如页面的URL
  9. 内建的对象或API不会总是自动地创建对象的实例,有些需要使用构造器进行实例化

适合初学者的面向对象JavaScript

  1. 最基本的OOP思想就是我们想要在程序中使用对象来表示现实世界模型, 并提供一个简单的方式来访问它的信息和功能
  2. 多态——用来描述多个对象拥有实现共同方法的能力
  3. javaScript没有创建Class类的声明,使用构建函数来定义对象和他们的特征,与Python实例化有所区别
  4. 构建函数就是JavaScript版本的类定义(首字母大写以便区别): html function Person(name) { this.name = name; this.greeting = function() { alert('Hi! I\'m ' + this.name + '.'); }; }
  5. 构造对象实例方法(关键字 new +含参函数): html var person1 = new Person('Bob', 'Smith', ...);
  6. 其他创建对象实例的方式1-使用Object构造该函数(可以将对象文本传递给函数作为参数): html var person1 = new Object({ name : 'Chris', age : 38, greeting : function() { alert('Hi! I\'m' + this.name + '.'); } });
  7. 其他创建对象实例的方式2-使用create()方法,基于现有对象创建新的对象实例: html var person2 = Object.create(person1); person2基于person1创建, 具有相同的属性和方法

对象原型

  1. JavaScript通过原型机制,从其他对象继承功能特性;这种继承机制与经典的面向对象编程语言的继承机制不同
  2. 每个函数都有一个原型(prototype)属性,该原型属性是一个对象
  3. 默认情况下, 所有函数的原型属性的 __proto__ 就是 window.Object.prototype
  4. 示例:

    function doSomething(){}
    doSomething.prototype.foo = "bar";
    console.log( doSomething.prototype );
    [output]:
    {
        foo: "bar",
        constructor: ƒ doSomething(),
        __proto__: {
            constructor: ƒ Object(),
            hasOwnProperty: ƒ hasOwnProperty(),
            isPrototypeOf: ƒ isPrototypeOf(),
            propertyIsEnumerable: ƒ propertyIsEnumerable(),
            toLocaleString: ƒ toLocaleString(),
            toString: ƒ toString(),
            valueOf: ƒ valueOf()
        }
    }
    
    原型链
  5. 原型链中的方法和属性没有被复制到其他对象——它们被访问需要通过“原型链”的方式

  6. 使用对象的__proto__属性可以访问其原型对象
在prototype属性中定义继承成员
  1. 继承的属性和方法是定义在对象的prototype 属性之上,其他的对象属性不会被继承
  2. prototype 属性包含(指向)一个对象,你在这个对象中定义需要被继承的成员
  3. Object.create() 实际做的是将原对象作为原型对象创建一个新的对象:,person2.__proto__返回对象person1
constructor属性
  1. 通过使用对象的constructor属性可以引用原始构造器创建一个和原对象一类的对象:var person3 = new person1.constructor('Karen'...);
  2. 获得某个对象实例的构造器的名字:person1.constructor.name
修改原型
  1. 向构造器的prototype属性添加新的方法,旧有对象实例的可用功能会被自动更新
  2. 一般来说, 在构造器内定义常属性比在prototype上定义更好
  3. 常见定义模式:在构造器(函数体)中定义属性,在 prototype 属性上定义方法,示例: html function Test(a,b,c,d) { // 属性定义 }; // 定义方法 Test.prototype.x = function () { ... } Test.prototype.y = function () { ... }

JavaScript 中的继承

  1. JavaScript继承的对象函数并不是通过复制而来,而是通过原型链继承(通常被称为原型式继承 —— prototypal inheritance)。
继承操作步骤
  1. 在父类构造器中声明继承的属性,在构造器原型上定义需继承的方法
  2. 定义子类的构造器函数(调用父类构造器函数,定义新属性):

    function Teacher(first, last, age, gender, interests, subject) {
      Person.call(this, first, last, age, gender, interests);
    
      this.subject = subject;
    }
    
  3. 设置子类的原型和构造器引用:

    Teacher.prototype = Object.create(Person.prototype);
    
    Teacher.prototype.constructor = Teacher;
    
  4. 添加或覆盖新的方法:

    Teacher.prototype.greeting = function() {
    
      alert('Hello. My name is ' + ' ' + this.name.last + ', and I teach ' + this.subject + '.');
    };
    
    总结
  5. 如果继承的构造函数不从传入的参数中获取其属性值,则不需要在call()中为其指定其他参数

  6. 每一个函数对象都有并且只有函数对象有prototype属性,prototype本身就是定义在Function对象下的属性
  7. 任何要被继承的方法都应该定义在构造函数的prototype对象里,并且永远使用父类的prototype来创造子类的prototype,这样才不会打乱类继承结构
  8. 对象成员总结:3种属性或方法
    • 定义在构造器函数中,用于给予对象实例的.以this.x = x形式定义,通常通过使用new关键字调用构造函数来创建
    • 直接在构造函数上定义、仅在构造函数上可用的,如Object.keys()
    • 在构造函数原型上定义、由所有实例和对象类继承
何时使用继承
  1. 当需要一系列拥有相似特性的对象,创建一个包含共有功能的通用对象,然后在特殊的对象类型中继承这些特性
  2. 不要临时或永久修改浏览器内置对象的原型

使用JSON

  1. JavaScript对象表示法(JSON): 将结构化数据表示为JavaScript对象的标准格式
  2. 如何访问JSON中的内容:使用.或括号表示法访问对象内的数据;访问对象中对象:通过属性名和数组索引链式访问
  3. 数组对象也是一种合法的JSON对象
  4. 不同于JS的对象,JSON只有字符串可以用作属性名称,但值仍旧可以为字符串,数字,数组,布尔及其它的字面值对象
示例:如何载入JSON数据
  1. 通过XMLHTTPRequestAPI创建HTTP请求,首先创建一个HTTP请求对象: html var request = new XMLHttpRequest();
  2. 使用open()函数打开一个新的请求(参数:请求方法和地址): html request.open('GET', requestURL);
  3. 设定返回对象类型病发送请求: html request.responseType = 'json'; request.send();
  4. 通过事件处理器(请求成功时触发)保存JSON数据: html request.onload = function() { var superHeroes = request.response; populateHeader(superHeroes); showHeroes(superHeroes); }
  5. 通过访问JSON对象中的数据进行其他处理
对象和文本间的转换
  1. parse(): 以文本字符串形式接受JSON对象作为参数,并返回相应的对象

    request.responseType = 'text';
    ......
    var superHeroes = JSON.parse(superHeroesText);
    
    
  2. stringify(): 接收一个对象作为参数,返回一个对应的JSON字符串 html var myJSON = { "name" : "Chris", "age" : "38" }; var myString = JSON.stringify(myJSON);

实践对象构造

  1. 绘制canvas画布,设定宽度和高度;创建随机位置和随机颜色函数
  2. 创建小球构造器,定义生成坐标、速度、颜色、半径等属性
  3. 通过ctx对象方法创建绘制小球方法
  4. 创建更新小球位置方法:检测是否到达边框,反转小球的速度方向来让它向反方向移动,每次调用移动速度值距离
  5. 创建动画:创建小球对象的数组,创建循环函数(循环生成指定数量小球,遍历绘制与更新),使用requestAnimationFrame() 递归运行循环函数
  6. 添加碰撞检测:遍历所有小球,对判断非当前的小球计算距离检测是否碰撞,如碰撞则更改两个小球颜色

客户端Web API

Web API简介

  1. API分类:浏览器内置API;第三方API
回调函数
  1. 由另一个函数作为参数的函数称为 (callback function "回调函数").
  2. 需要异步操作(需使用第一步操作返回结果,容易出错): html var position = navigator.geolocation.getCurrentPosition(); var myLatitude = position.coords.latitude;
  3. 设计成回调函数: html navigator.geolocation.getCurrentPosition(function(position) { ... });
API工作方式
  1. 通常基于对象进行交互,将使用的数据和提供的功能封装在对象属性和方法中
  2. API对象通常包含构造函数来创建用于编写程序的对象实例;其次API对象通常接受可调整的options对象作为参数,以适应程序所需的确切环境
  3. 有可识别的入口点,如文档对象模型的入口(其他个别API涉及要创建特定的上下文): html var em = document.createElement('em'); <!-- 创建一个新的元素 --> var para = document.querySelector('p'); <!-- 引用一个已经存在的元素 --> em.textContent = 'Hello there!'; <!--给em元素增加文本 --> para.appendChild(em); <!--embed em inside para -->
  4. 使用事件来处理状态的变化,如:XMLHttpRequest对象的实例(每一个实例都代表一个到服务器的HTTP请求,来取得某种新的资源)有很多事件可用,例如onload事件在成功返回时触发
  5. 在适当的地方有额外的安全机制,如只在HTTPS页面工作或需用户许可权限

操作文档对象模型

  1. 3种Web API访问的主要部位:
    • Window对象,当前窗口,可以返回窗口大小,操作载入窗口的文档,为当前窗口绑定事件处理器等
    • Navigator对象,浏览器存在于web上的状态和标识(即用户代理),可以获取用户地理信息、偏爱语言、多媒体流等
    • Document对象,载入窗口的实际页面,可以返回和操作文档中HTML和CSS上的信息
获取操作对象
  1. 选择一个元素,并将它的引用存储在变量中 html var link = document.querySelector('a');
  2. querySelector()调用匹配在文档中查找到的第一个匹配元素,Document.querySelectorAll()方法选中文档中所有匹配选择器的元素,并将其引用存储在一个数组中
  3. 其他获取元素应用方法:Document.getElementById(),选择一个id属性值已知的元素
创建并放置新的节点
  1. 创建新元素:使用Document.createElement(),如var para = document.createElement('p');
  2. 为新元素赋予内容(如文本):para.textContent = 'We hope you enjoyed the ride.';
  3. 放置新元素到父容器中:使用Node.appendChild()方法,如ect.appendChild(para);
  4. 创建新节点:使用Document.createTextNode()创建一个文本节点,参数为文本,放置方法同上
移动和删除节点
  1. 移动节点:sect.appendChild(linkPara);,linkPara是指向该段落唯一副本的引用,重新放置会移动其位置
  2. 删除节点:无法通过节点方法删除自身,必须通过父节点删除-linkPara.parentNode.removeChild(linkPara);
操作样式
  1. 方式1:通过HTMLElement.style属性直接修改内联样式,如para.style.backgroundColor = 'black';
  2. 方式2:通过 Element.setAttribute()方法设置class属性,并创建对应类别的样式(更适用于大型项目)
注意
  1. 使用JavaScript创建静态内容是毫无意义的—最好直接将其写入HTML
评估-创建购物清单
  1. 创建需要使用元素的引用变量
  2. 创建按钮响应事件函数:
    • 取出输入值并清空输入框
    • 创建新条目对应元素并组织关系
    • 填充新条目内容
    • 放置新条目
    • 创建新条目按钮响应事件函数
  3. 使用focus()方法设置聚焦输入框

从服务器获取数据-AJAX

XMLHttpRequest请求步骤
  1. 构造请求目标URL
  2. 使用XMLHttpRequest()构造函数创建一个新的请求对象 html var request = new XMLHttpRequest();
  3. 使用open()方法指定请求资源的HTTP request method , 以及目标URL html request.open('GET', url);
  4. 设置期待的响应类型—由请求的responseType属性定义,XHR默认返回txt文本类型 html request.responseType = 'text';
  5. 使用请求的onload 事件处理器来处理返回的数据(response) html request.onload = function() { poemDisplay.textContent = request.response; };
  6. 发送请求 html request.send();
Fetch和Promises
```html
fetch(url).then(function(response) {
  response.text().then(function(text) {
    poemDisplay.textContent = text;
  });
});
```

1. 执行异步操作:传递给then()是一段不会立即执行的代码,当完成指定的操作时代码会被运行(代替xhr的响应事件) 2. promise 解析时会自动将响应结果作为参数传递给then()内的函数 3. 执行响应的text()方法将响应作为原始文本返回 4. 另一种写法; html fetch(url).then(function(response) { return response.text() }).then(function(text) { poemDisplay.textContent = text; });

评估
  1. 返回请求状态的范式(fectch使用reponse.ok和response.status) html request.onload = function() { if(request.status === 200) { products = request.response; } else { console.log('Network request failed with response ' + request.status + ': ' + request.statusText); } }

第三方API

  1. 需要通过 <script>元素的src属性连接到第三方服务器所开放的JavaScript库
  2. 为了保证安全性,通常需要先申请密钥才能使用API
  3. 通常使用第三方API的步骤:
    • 查阅有关文档
    • 获取开发者密钥
    • 连接API到你的应用
    • 通过API请求数据
    • 显示返回的数据

画图

  1. canvasWebGLS不深入学习,有需要时查阅
  2. 画布左上角的坐标是(0, 0),横坐标(x)轴向右延伸,纵坐标(y)轴向下延伸
简单使用<canvas>
  1. 在HTML插入<canvas> 元素,插入反馈信息
  2. 创建画布并确定尺寸 html var canvas = document.querySelector('.myCanvas'); var width = canvas.width = window.innerWidth; var height = canvas.height = window.innerHeight;
  3. 获取画布上下文并完成设置 html var ctx = canvas.getContext('2d');
  4. 填充矩形 html ctx.fillStyle = 'rgb(0, 0, 0)'; ctx.fillRect(0, 0, width, height);
  5. 描边线条 html ctx.strokeStyle = 'rgb(255, 255, 255)'; ctx.strokeRect(25, 25, 175, 200); ctx.lineWidth = 5;

视频和音频API

不深入学习,有需要时查阅

客户端存储

  1. Web Storage API提供非常简单的语法用于存储和检索较小的、由名称和相应值组成的数据项。存储简单数据比如用户的名字,用户是否登录,屏幕背景颜色等等
  2. IndexedDB API 为浏览器提供完整的数据库系统来存储复杂数据。可以用于存储从完整的用户记录到甚至是复杂的数据类型,如音频或视频文件。
  3. 不深入学习,有需要时查阅

注:转载本文,请与作者联系




如果觉得文章对您有价值,请作者喝杯咖啡吧

|
donate qrcode

欢迎通过微信与我联系

wechat qrcode

0 Comments latest

No comments.