JS复习

本文全面回顾JavaScript的历史,从最初的Mosaic浏览器到Netscape Navigator,讲解了JavaScript的诞生和发展。深入探讨JavaScript的特点,如解释性语言、单线程和ECMA标准。介绍了JavaScript的三大组成部分:ECMAScript、DOM和BOM,以及基本语法,如变量声明、类型转换和运算符。此外,详细阐述了函数与作用域、闭包的概念及其应用。最后,涉及了对象创建、事件处理、异步加载等高级主题,帮助读者深入理解JavaScript的精髓。
摘要由CSDN通过智能技术生成

一、初始JavaScript
1.Mosaic是互联网历史上第一个普遍使用和显示图片的浏览器1993年问世。
2.后来由于商标权转让,原本的开发团队又开发了Netscape Navigetor网景浏览器,也是很多浏览器的前身。
3.JS作为Netscape Navigetor浏览器的一部分首次出现在1996年,最初设计是改善网页的用户体验,作者是Brendan Eich.
4.起初JS被命名liveScript,后因为跟Son公司合作改名为JavaScript,后来Son公司被Oracle公司收购,所有版权归Oracle所有。

二、浏览器的组成
1.浏览器主要有两部分组成,shell和内核部分,内核还包含了许多东西
2.渲染引擎,内核里渲染引擎主要负责html和CSS部分,定义了语法规则、渲染规则以及渲染路径和速度等等。
3.js引擎,2001年发布了ie6,首次实现对js引擎的优化。
4.2008年Google发布了Chrome,它是采用优化后的js引擎,引擎代号V8,因能把js代码直接转化成机械码0101来执行,进而以速度快而闻名。
5.后来Firefox也推出了具有强大功能的js引擎
Firefox 3.5 TraceMonkey(对频繁执行的代码做了路径优化)
Firefox 4.0 JeagerMonkey
6.其他模块。

三、JavaScript特点
1.解释性语言——不需要编译代码,可以跨平台,像php、js、jsp都是解释性语言。
2.单线程——js是单线程的语言,同时只能执行一件事情
3.ECMA标准——为了统一js的规则,推出了ECMA标准,因此js也称为ECMAScript。

四、JavaScript三大部分:ECMAScript、DOM、BOM
1.ECMAScript是符合ECMA标准的基本javascript。
2.DOM是Document Object Model文档对象模型,可以操作页面的代码,可以操作html和css部分。DOM是非常非常重要的部分。
3.BOM是Browser Object Model浏览器对象模型,操作浏览器shell的。因为每一个浏览器厂家的不同,导致我们在每一个浏览器操作BOM都不一样.

五、JavaScripr的基本语法
1.变量声明
• Js是一种弱数据类型的语言,任何类型的变量都用关键字Var来声明。
// var arr = [1,2,3];
// var num = 123;
// var steing = “abc”;
• 赋值可以在声明的的同时赋值,也可以在后面赋值。
// var num = 123;
// var num;
// num = 123;
• 这两种方法是一样的。
• 同时有一种单一Var模式,
//var num1 = 123,
// num2 = 234,
// num3 = 456;
• 变量名上下对齐,这样结构更清晰,也能节省很多代码。

2.变量命名规则
• 以英文字母开头或者_和$符开头。
• 变量名可以包含数字
• 不可以使用系统自带的关键字,保留字

3.值类型———>数据类型
• 不可改变的原始值
• 主要有 Number String Boolean undefined null 堆数据
• 引用值 数组Array 对象Object 函数function 栈数据

六、JavaScrpit语句的基本规则
1.语句后面要用英文“ ; ”结束
2.js语法错误会引发后续代码的终止,但不会影响其他的JS代码块,这里仅限于逻辑错误和低级语法错误会导致代码全部执行不了。
3.书写规范

七、JavaScrpit运算符
1.“ + ”数学上相加的功能和字符串拼接 “ - * / % ” 数学运算。
2.相同的还有“ ++ == – += -= > < …”等等
3.逻辑运算符 && || !
• && 的作用是结果是true的时候才会继续执行,第一个就错了第二不会执行,如果都是true的话返回最后一个
• ||的作用是只要有一个表达式是true的,后面的就不走了,并且返回的结果是这个正确的表达式的结果,全是false表达式返回的结果就是false。
• &&可以当做一种短路语言使用 ||可以当做赋初值的作用。
4.默认为False的值
• unedfined null ” ” NaN 0 false

八、类型转换
壹、显示类型转换
• 用typeof可以检测数据的类型
// console.log(typeof(123)); // Number
• typeof返回的结果有六种:number string boolean undefined object function.
• 数组和null都属于object
• NaN属于number,虽然是非数,但是也属于数字
• typeof返回的结果是字符串

2.Number(mix){美克斯}【混合】
• 这个方法是可以把其他类型的数据转换成数字类型的数据。

3.parseInt(string,radix) {帕森特 、 rui die KS}【基数】
• 这个方法是将字符串转换成整型类型数字的。其中第二个参数radix基底是可以选择的参数。
• 当radix为空的时候,这个函数的作用仅仅是将字符串转换成number类型
• 当参数string里面既包括数字字符串又包括其他字符串的时候,它会将看到其他字符串就停止了,不会继续转换后面的数字型字符串了。
// parseInt(‘123abc123’) // 123;
// parseInt(‘abc123’) // NaN;
// parseInt(‘123’) // 123;
// parseInt(‘true’) // NaN;
• 当radix不为空的时候这个函数可以用作进制转换,把第一个参数的数字当成几进制的数字转换成十进制
• radix参考范围是2–36
// var demo = 10;
// parseInt(demo,16) //16

4.parseFloat(radix){帕斯弗露特}
• 这个方法和parseInt类似,是将字符串转换成浮点类型的数字,碰到第一个非数字类型停止
• 只能识别第一个小数点及后面的数字,第二个小数点不能识别
// parseFloat(‘123.2.3’) // 123.2
// parseFloat(‘132.2abc’) // 123.2
// parseFloat(‘123.abc1’) // 123

5.toString(radix)
• 这个方法和前面的不同,它是对象上的方法,任何数据类型都可以使用,转换成字符串类型,涉及到包装类
• 同样是radix基地可选参数,为空仅仅将数据转换成字符串。
// var demo = 123;
// typeof demo.toString(); // string123;
// typeof true.toString(); // stringtrue;
• 当写了radix时代表要将这个数字转换成几进制的数字型字符串
// var dome = 10;
// demo.toString(16) // A
• undefined和null没有toString方法

6.String(mix)
• 和Number类似把任何类型转换成字符串

7.Boolean(mix)
• 和Number类似把任何类型转换为Boolean

贰、隐式类型转换
1.isNaN()
• 这个方法可以检测是不是非数类型,调用的Number方法

2.算数运算符
• ++就是将现有数据调用Number之后,自身加一
• + - * / 执行之前都会先进行类型转换,换成数字在运算

3.逻辑运算符
• && || ! 都会调用Boolean转换成布尔值看看结果是ture还是false,返回结果还是本身表达式的结果
// !abc; // false
4.不发生类型转换的比较运算符
• ===严格等于 !==严格不等于

九、预编译 [precompile]
• 函数声明提升:函数声明提升是一种整体提升,它会把函数声明和函数体一起提升到前面
• 变量声明提升:变量声明提升是一种局部提升,它仅仅将变量的声明提前了,但是并没有将赋值一起提升

1.JS运行三部曲
• 语法分析
• 预编译
• 解释执行

2.预编译前奏
• imply global {In 普莱 、 苟楼卜}
• 暗示全局变量,如果任何变量未经声明就赋值使用,此变量归Window所有,并且成为Window对象的一个属性
• 一切声明的全局变量,都是Window属性
• 未经声明的全局变量可以用delete操作来删除
• 函数在执行的前一刻产生一个上下文,Activeaction Object对象
• 这个对象是空的,但是里面有一些看不见的隐式属性:this:window属性和arguments[];属性

3.预编译四部
• 创建AO对象
• 寻找形参和变量声明并当做属性名添加到AO对象中,值为undefinen。 //函数声明不叫变量
• 将实参形参相统一
• 在函数体里寻找函数声明,将函数名当做属性名,值为这个函数的函数体
// function test (a,b) {
// console.log(a)
// function a () {}
// a = 222;
// console.log(a)
// function b () {};
// console.log(b)
// var b = 111;
// var a;
// }
// test(1);
• var b = function () {} 这种不叫函数声明,这个函数是给b赋值的,b变量是声明
• 在第四步寻找函数声明并不会把赋值成function(){},执行到这一行的时候才会赋值成这个函数

十、函数与作用域与闭包
壹、函数部分
1.函数声明有3种方式
• var demo = function () {}; 函数表达式
• function demo () {}; 函数声明
• var demo = function xxx () {};命名函数表达式 //没用
• 每一个函数里面都有一个类数组属性arguments,这个属性里面存的就是实参
• 每一个函数有一个length属性,这个属性存的是形参的数量
• 每一个函数都会有一个return,如果不写的话函数会自动加一个return
• return的功能有两个:返回这个函数的执行结果、终止函数的执行
// function test(a,b) {
console.log(a + b);
return;
console.log(‘hello’);
}
test(1,2); // 打印结果3 不会打印hello

贰、作用域
• 定义:变量(变量作用域又称为上下文)和函数生效(能被访问)的区域
• javaScriot的函数是可以产生作用域的!
• es5中的作用域只有全局作用域和函数作用域两种,es6新添加的块级作用域
// var demo = 123; // 全局变量
// function test () {
// var demo = 234; // 局部变量
// console.log(demo);
// var demo1 = ‘hello’;
// }
// test(demo); // 打印234 就近打印局部变量,没有局部变量打印全局变量
// console.log(demo1); // 报错 我们的全局作用域无法访问局部作用域
• 函数作用域就好像一个屋子,里面的可以拿外面的东西,外面的不能拿里面的东西
• 在函数作用域里声明变量没有用var的话,那么就生成了一个全局变量
• 两个不同的作用域(除了全局作用域)是不能相互访问的

叁、作用域链 (scope chain){S狗扑 chen}
• 既然函数存在作用域,函数有可以嵌套,那么作用域直接就会产生嵌套关系,这个时候就产生的作用域链
• 当代码在一个环境中执行时,会创建变量的一个作用域链来保证对执行环境有权访问的变量和函数的有序访问
• 作用域链第一个对象始终是当前执行代码所在环境的变量对象
// function demo () {
// var dome_a = 1;
// function test () {
// var demo_a = 2;
// console.log(demo_a);
// }
// test();
// }
// demo();
• 本着对执行环境的有权和有序访问,每个函数的自身作用域总在作用域链的最顶层,下一层就是这个函数的父级函数作用域…直到全局作用域
• 因此test执行的时候打印的demo_a是本身作用域中的’2’而不是’1’如果自身作用域没有demo_a的话系统就会沿着作用域链向下找到dome作用域的demo_a

肆、闭包 [closure]
1.什么是闭包
• 闭包就是能够读取其他函数内部变量的函数
• 不同的作用域之间不能互相访问,但是如果在一个函数内部在定义一个函数并且这个内部函数与外部函数的变量有所关联,
那么就可以返回这个函数来访问外部函数里面的变量,所以在本质上闭包就是将函数内部与函数外部连接起来的桥梁
// function a (){
// var dome1 = 123;
// add = function(){
// demo1 ++;
// }
// return function(){
// console.log(demo1);
// };
// }
var demo = a ();
demo(); // 123
add();
demo(); // 124
• 当函数执行完函数的执行上下文就会被销毁,自然就无法访问里面的变量了,但是我们这个函数返回了一个依赖于这个函数的新函数,
也就是说这个没有被销毁的新函数的作用域链中存在着原本函数作用域的引用,就导致原本函数的上下文不会被销毁,返回的新函数是原本函数的闭包函数

2.使用闭包的注意点
• 闭包会使函数的变量都保存在内存中,内存消耗很大,不能滥用闭包,否则会造成网页的性能问题,IE会造成内存泄漏
解决的方法就是在退出函数时,将不使用的局部变量全部删除
• 闭包会在父函数外部改变父函数内部的值,如果把闭包当对象使用,那么就把闭包当做它的公用方法,把内部变量当做它的私有属性。
(不要随便改变父函数内部变量的值)
// var name = ‘global’;
// var obj = {
// name:’obj’,
// getName:function () {
// return function () {
// console.log(this.name);
// }
// }
// }
// obj.getName()();
• 累加器的例子
// function a () {
// var num = 1;
// function addNum () {
// num ++;
// console.log(num);
// }
// return addNum;
// }
// var demo = a ();
// demo();
// demo();
// var demo1 = a();
// demo1();
// demo1();

伍、立即执行函数
• 立即执行函数是解闭包的一个重要方法,但是注意闭包是没有办法解除的,只能通过一个新的闭包来消除上一个闭包的影响
• 立即执行函数不需要被定义,直接执行,执行完释放,经常用作初始化
• 函数声明不能被执行,但是函数表达式可以
// (function (){}())
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
// function returnB() {
// var arr = [];
// for(i = 0; i < 10; i ++){
// arr[i] = (function(){
// console.log(i);
// }())
// }
// return arr;
// }
// var save = returnB();
// console.log(save);
// for(j = 0; j < 10; j ++){
// save[j];
// }

十一、对象、构造函数与包装类
1.对象的创建方式有三点
• 对象字面量
// var obj = {};
• 这样的方式是最简单最常用的方法
• 对象里面有属性,属性之间用逗号相隔,每条属性都有属性名和值,属性名和属性值用分号分隔

2.构造函数 [constructor]
• 构造函数也分为两种,系统自带的构造函数和自定义的构造函数
• 创建对象的构造函数Object()
// var object = new Object();
通过这条语句就创建了一个空对象,它的作用和 var obj = {}; 的作用一样
• 系统自带的构造函数还有Number(),String(),Boolean(),Array()

3.自定义构造函数
• 自定义的构造函数是最常用的一直构造函数
// var function Person () {};
// var operson = new Person ();
// typeof operson // object
• 用new操作符创造出来的对象,尽管使用的是一个构造函数,但是之间没有关联
// function Person (name,age) {
// this.name = name;
// this.age = age;
// }
// var person = new Person(‘zhangsan’,18);
// console.log(person.name);
• 创建对象的时候只有new才会有this
• 重点:为什么可以用new操作符创建出相互独立的对象呢?
• 用new操作符的时候,这个new在构造函数里面隐式的创建了一个this对象,并且最后返回了这个this对象。
function Person (name) {
//var this = {};
this.name = name;
//return this;
}
• 如果在构造函数首行手动创建一个对象,比如that对象,然后返回that,那么里面的this就没用了,属性赋值就用that了
// function Person (name) {
// var that = {
// name: ‘lisi’
// };
// that.name = name;
// return that;
// }
// var person = new Person (‘demo’);
// console.log(person.name)
• 如果最后返回的是对象,那么this就失效,但是如果显示返回的是原始值那么this还是有效的

4.属性的增删改查
• 增:可以通过对象名+点属性名的方法来给对象添加新的属性并且赋值
// var obj = {};
// obj.name = ‘xiaoming’
• 改:修改的操作和增加是一样的,只要调用相同的属性名然后赋一个新值就可以了
// var obj = {
// nama:’demo’;
// }
// obj.mame = ‘tan’;
• 查:查看属性的功能 console.log(xxx)
• 删:删除属性需要借助delete操作符
// var obj = {
// name = ‘scerlett’
// }
// obj.name; // scerlett
// delete obj.name;
// obj.name; // undefined
• 包装类
• So Seay !!!

十二、原型与原型链
壹、原型:prototype
1.原型的定义:原型是function对象的一个属性,它定义了构造函数制造出来的对象的公有祖先,通过该构造函数产生的对象,
可以继承该原型的属性和方法,原型也是对象
// function Person () {}
• 定义一个构造函数,Person.prototype这个属性就是这个构造函数的原型,这个属性天生就有的,并且这个属性的值也是一个对象
• 可以在person.prototype上面添加属性和方法,每一个构造出来的对象都可以继承这些属性和方法
• 虽然每一个对象都是独立的,但是他们都有共同的祖先,当访问这个对象属性的时候,如果他没有这个属性,就会向上查找,
找到它原型,然后在原型上访问这个属性
2.利用原型特点可概念,可以提取公有属性
• 可以吧每一个对象都有的公有属性不写在构造函数里面,而是提取到原型上,这样当构造函数构造大量的对象的时候就不需要走多次构造函数里面的赋值语句了
而只需要走一遍,每个对象调用属性的时候直接上原型上查找就可以了

3.对象如何查看原型
• 用构造函数构造对象的时候,就会隐式创建一个this对象,这个this对象里面有一个默认的属性叫做proto属性,这个属性的值就是指向对象的原型
• 当查找的属性是自身没有的属性的时候,就会查找proto这个属性,然后这个属性指向原型,所以就到原型上查找属性了
• 注意:prototype是函数的属性,proto是对象的属性

4.如何查看构造自身的构造函数
• 在prototype里面,有一个隐式的属性叫做constructor,这个属性记录的就是对象的构造器,里面存的就是构造函数
// console.log(person.constructor); //Person();

贰、原型链
1.有了原型,原型还是一个对象,那么这个名为原型的对象自然还有自己的原型,这样的原型上还有原型的结构就构成了原型链
// Gra.prototype.firsName = ‘scarlett’
// function Gra () {
// this.name = ‘grandfather’;
// this.sex = ‘male’;
// }
// var grandfoo = new Gra();
// // garndfoo.word = ‘hello’
// Foo.prototype = grandfoo;
// function Foo () {
// this.age = ‘18’;
// this.money = ‘100’;
// }
// var father = new Foo();
// function Son () {
// this.name = ‘son’;
// }
// Son.prototype = father;
// var son = new Son();
• Foo创造出来的每一个对象都继承来自grandfoo对象,son的每一个对象都继承来自father这个由Foo创造出来的对象,
这样son就可以继承上面Foo和Gra的所有属性
• 这种链式的查询结构叫做原型链,最终的尽头是Object.portotype这个对象
• 如果没有规定原型的对象,它的原型就是Object.prototype

2.但是并不是所有的对象都有原型,比如使用Object.create方法
• Object.create()方法需要写一个参数,这个参数就是这个对象的原型,如果要构造一个和var obj = {};一样的对象,就需要写:
// var obj =Object.create(Object.prototype);
• 也可以写一个自定义的属性,让他成为原型

不懂!!!!!!!!!!!!!!!!!!!!!!!!

3.原型链上的增删改查
// Person.prototype.arr[1,2,3];
// var person1 = new Person();
// var person2 = new Person();
// person1.arr.push(4);
// console.log(person2); // 1 2 3 4
• 删:删除属性需要借助delete操作符,对象不能删除原型上的属性

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

十三、继承、this
1.this的一些问题:
• 函数内部的this默认指向window,可以使用call / apply来改变this的指向 区别:后面传参形式不同
// function person () {
// this.name = ‘scarlett’;
// console.log(this);
// }
// person();
• 现在this指向window,name属性自然就是window上的全局属性
// var obj = {};
// person.call(obj); //Object.{name:’scarlett’}
• 如果这个函数还有参数的话,只要把实参的值写在call后面并且用逗号隔开
// function person(name,age){
// this.name = name;
// this.age = age;
// }
// var obj = {};
// person.call(obj,’scarlett’,18);
// console.log(obj.name);
• apply和call基本没什么区别,唯一的区别就是call后面的参数是一个一个传

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值