一.前言

通过HTML和CSS的学习,我们可以做到实现静态的页面。然而实现动态页面或者实现交互功能就离不开JavaScript。所以在这里对半个月学习js做一个总结。

二.了解JavaScript

2.1 什么是JS

JavaScript(简称“JS”) 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名的,但是它也被用到了很多非浏览器环境中,JavaScript 基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式(如函数式编程)风格。

2.2 组成部分

  • ECMAScript:描述了该语言的语法和基本对象。
  • 文档对象模型(DOM):描述处理网页内容的方法和接口。
  • 浏览器对象模型(BOM):描述与浏览器进行交互的方法和接口。

三.重要知识点总结

3.1 如何引入js

  • 页面内嵌
    为符合 web 标准(w3c 标准中的一项)结构(html)、行为(js)、样式(css)
    相分离,通常会采用外部引入。
  • 一个文件中可以包括多个 css,js——不混用
  • 特殊写页面,大部分写在外部——不混用
  • 如果同时写了内部的 js 和外部的 js,那么是外部的 js 文件显示出来

3.2 基本语法

3.2.1 变量(variable)
HTML,css 不是编程语言,是计算机语言,编程语言需要有变量和函数
变量是存放东西,方便后续使用的框。

  • var a ;a =100;可以简化写成 var a=100;
  • 单一var声明法var a,b,c,d,e; 的标准写法是
    var a = 10; var b = 10; var c = 10; var d = 10; var e = 10;

3.2.2 命名规则(用接近的英文单词)

  • 变量名必须以英文字母、_、$ 开头
  • 变量名可以包括英文字母、_、$、数字
  • 不可以用系统的关键字、保留字作为变量名

3.2.3 值类型

  • 不可改变的原始值(栈数据)栈 stack
    (Number、String、Boolean、undefined、null)
  • 引用值(堆数据)大致上放堆 heap 里面
    (array 数组、Object、function … data、RegExp 正则)

3.2.4 js语句基本规则

  • 语句后面要用分号结束“;”但 function test(){},for(){},if(){}后面都不用加分号
  • js 语法错误会引发后续代码终止,但不会影响其它 js 代码块
    错误分为两种:
    1)低级错误(语法解析错误),不能写中文
    2)逻辑错误(标准错误,情有可原,错的那个执行不了)
  • 书写格式要规范,“= + / -”两边都应该有空格

3.3 js运算符

3.3.1 运算操作符

  • “+”作用:数学运算、字符串链接(任何数据类型加字符串都等于字符串)
  • %,摩尔,模,是取余数的意思
  • “-”,“*”,“/“,“%”,”=“,“()” 优先级”=“最弱【赋值符号优先级最低】,”()”优先级较高

3.3.2 比较运算符

  • “>”,”<”,”==”,“>=”,“<=”,”!=”比较结果为 boolean 值。但凡是运算符,都是要有运算的
    用到布尔值,true 或 false[字符串的比较,比的是 ASCII 码(七位二进制 0000000) >, <]
  • = =,等不等于(NaN 不等于任何东西,包括他自己,NaN 得不出数,又是数字类型,就是 NaN)
  • ->=,<=,!=是否不等于,非等。比较结果为 boolean 值:true 和 false

3.3.3 逻辑运算符
“&&”,“||”,“!“运算结果为真实的值

  • “&&”与运算符:两个表达式:先看第一个表达式转换成布尔值的结果是否为真,如果结果为真,那么它会看第二个表达式转换为布尔值的结果,然后如果只有两个表达式的话,只看看第二个表达式,就可以返回该表达式的值了,如果第一位布尔值为 false,不看后面的,返回第一个表达式的值就可以了。如果是三个或多个表达式,会先看第一个表达式是否为真,如果为真,就看第二个表达式,如果第一个是假,就返回第一个值,当是真的时候就往后走,一旦遇到假,就返回。
  • &与运算:我们一般不用。按位与,相同为1,不同为0(对齐补零)
  • “||”或运算符:看第一个表达式是否为真,如果为真,则返回第一个值,碰到真就返回如果第一个表达式是假,就看第二个表达式,如果第二个是最后一个,就返回第二个的值。
  • “!“非运算符,否的意思。先转成布尔值,再取反

被认定为 false 的值:转换为布尔值会被认定为 false 的值 undefined,null,NaN,
“”(空串), 0, false

3.4 初识引用值

3.4.1 数组
所有的JavaScript变量都是对象。数组元素是对象。函数是对象。因此,你可以在数组中有不同的变量类型。你可以在一个数组中包含对象元素、函数、数组。
3.4.2 对象 object
var obj = {
里面存属性和方法
key 属性名:value 属性值,
}
在{}面用。属性与属性之间用逗号隔开
//属性值可以双引号或单引号;属性名是为了方便找到他,只是一个辅助。

3.5 操作符

3.5.1typeof
typeof 能返回的六种数据类型(区分数字类型)
number、string、boolean、undefined、object、function
(null 返回 object,最早是代替空对象的)

如果定量没定义就直接访问,就 a is not defined 报错;有一种特殊情况,当且仅当把未定义的变量放到 console.log(typeof(a));里面就访问,不报错,返回 undefined
3.5.2 显示类型转换

  • Number(mix) 是想把里面的东西转换成数字
var demo = undefined;
 var num = Number(demo); 
 console.log(typeof(num) + “:” + num);
 答案显示 Number:NaN

(可以把null、空字符串、false转换为0;把true转换为1)

  • parseInt(string,radix)parse 是转化,Int 是整型,整数,目的是把里面转换成整数。parseInt 从数字类开始看,看到非数字类为止,返回原来的数。
    (把空字符串、true、false、null转换为NaN)
var num = parseInt(demo ,radix);

radix 写成 16,系统会认为是以 16 进制为基底,10(一零)是 16 进制的一零,是
以 16 进制为基底,把他转成为 10 进制的数字(就是 16),上面是以目标进制为基底,
转换成十进制(radix 范围是 2-36)

  • parseFloat(string):转换成浮点数字,就是正常小数。parseFloat 从数字类开始看,看到除了第一个点以外的非数字类为截止,返回前面的数。
  • toString
    - 想把谁转换成字符串,就写成谁.toString
    - undefined 和 null 不能用 toString
    - toString(8);这里的 radix 意思是以十进制为基底,转换成目标进制(即 8 进制)
  • String(mix):String(mix)转换成字符串,写什么都成了字符串
  • Boolean():转换成布尔值 false 和 true

3.5.3 隐式类型转换

隐式类型转换是跟你转换了也不知道
隐式类型转换内部隐式调用的是显示的方法
隐式类型转换包括 isNaN () ,++,--, +/-(一元正负),+,*,% ,&&,|| ,!,<,>,<= ,>= ,== ,!=
  • isNaN ():当你把一个数放到()里,它能判断是不是 NaN,先把括号里面的放到 number里面转换,然后返回来
  • ++/-- (加加减减) +/-(一元正负)
    (尽管转换不成数字,也会转换成数字类型,因为里面隐式的调用了一个 number)
  • “+”:+隐式类型会转换成 string,当加号两侧有一个是字符串,就用调用 string,把两个都变成字符串
  • " * ,%" 乘和模都会转换成 number.
  • && || !与或非,都是有类型转换的,不过是返回的是表达式的值,不是隐士类型转换的值,但是判断是一个类型转换的值
  • < > <= >=
有数字相比较的,就会隐士类型转换成数字类型
两个字符相比,比较ASCⅡ
  • == !=
    undefined == null //答案 true
    NaN ==NaN //答案 false,NaN 是唯一一个连自己都不等于的

3.5.4 不发生类型转换

  • ===绝对等于(三个等号) !==绝对不等于
    (NaN =NaN //答案 false 特殊的)
    【toFixed(3)是保留三位小数的意思,四舍五入】
    提示:
    alert(‘a’);就是弹出框,相当于 console.log

3.6 函数function

function 随便起个名(){};
编程讲究高内聚,弱偶合。
3.6.1 定义

  • 函数声明
    a.定义一个函数可以先写一个 function,函数就是另一个类型的变量。
    b.function 随便起个名(){函数体};
    c.函数名起名:开发规范要求,函数名和变量名如果由多个单词拼接,必须符合小驼峰原则(第一个单词首字母小写,后面的首字母大写)
    d.c 语言和 c++,他们打印指针,会输出指针的地址,而 js 这种弱数据语言(解释性语言)永远不输出地址,输出地址指向房间
  • 函数表达式
    a.命名函数表达式
    b.匿名函数表达式

3.6.2 组成形式

  • 函数名称
    function test(){}其中 function 是函数关键字,test 是函数名,必须有(){},参数可有可没有,参数是写在()括号里面的。如果写成 function test(a,b){},相当于隐式的在函数里面 var a,var b 申明了两个变量,()括号里面不能直接写 var
  • 参数(可有可没有,但是高级编程必有)
    a.形参(形式参数):指的是 function sum(a,b){}括号里面的 a 和 b
    b.实参(实际参数):指的是 sum(1,2);里面的 1,2
    (天生不定参,形参可以比实参多,实参也可以比形参多。js 参数不限制位置,天生不定参数在每一个函数里面都有一个隐式的东西 arguments 这个是实参列表)
    在 if 里面定义函数声明 function 是不允许的
  • 返回值 return
    a.结束条件和返回值 return,return 有终止函数的功能
    b.没写 return,实际上是加上了一个隐式的 return
    c.return 最常用的是返回值。本意是把一个值返回到函数以外

3.7 全局的预编译三部曲

  1. 生成了一个 GO 的对象 Global Object(window 就是 GO)
  2. 找形参和变量声明,将变量和形参名作为 GO 属性名,值为 undefined
  3. 在函数体里面找函数声明,值赋予函数体

(任何全局变量都是 window 上的属性没有声明就是赋值了,归 window 所有,就是在 GO 里面预编译)
(想执行全局,先生成 GO,在执行 test 的前一刻生成 AO在几层嵌套关系,近的优先,从近的到远的,有 AO 就看 AO,AO 没有才看 GO)

3.8 闭包

3.8.1 什么是闭包
当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄露。
内存泄漏就是内存占用,内存被占用的越多,内存就变得越来越少了,就像内存被泄露了一样
(但凡是内部的函数被保存到外部,一定生成闭包
3.8.2 闭包的作用

  • 实现公有变量
    每回调用 counter 就会在原有基础上加一次
    每回调用 counter 就会在原有基础上加一次
  • 可以做缓存(存储结构)
    eg:eater。缓存是外部不可见的,但是确实有存储结构

    答案 101 和 100,思考过程:说明两个用的是一个 AO

    答案 i am eating banana,eat 和 push 操作的是同一个 food
    在 function eater(){里面的 food}就相当于一个隐式存储的机构
    obj 对象里面是可以有 function 方法的,也可以有属性,方法就是函数的表现形式
  • 可以实现封装,属性私有化。
  • 模块化开发,防止污染全局变量

3.9 立即执行函数

3.9.1 定义
此类函数没有声明,在一次执行过后即释放(被销毁)。适合做初始化工作。针对初始化功能的函数:只想让它执行一次的函数立即执行的函数也有参数,也有返回值,有预编译。(写成(function abc(){}())也调用不到)
3.9.2 立即执行函数的两种写法

  • (function (){}());在 W3C 建议使用这一种
  • (function (){})();
    只有表达式才能被执行符号执行
    能被执行符号执行的表达式,这个函数的名字就会被自动忽略(放弃名字)
    能被执行符号执行的表达式基本上就是立即执行函数
    函数声明和函数表达式是两个东西,虽然都能定义函数
    函数声明:function test ( ){} 函数表达式:var test = function( ){}
  • 闭包会导致多个执行函数共用一个公有变量,如果不是特殊需要,应尽量防止这种
    情况发生。

3.10 对象

3.10.1 创建方法

  • var obj = {} 对象字面量/对象直接量 plainObject

javascript要学多长时间 javascript学完要多久_javascript


双引号和单引号都是表示的字符串,写双引号也可以写单引号,但是为了跟后端 php配合最好写单引号。如果要打印一个单个的引号,用正则表达式转义字符\注意等号和冒号的用法 obj.say = function(){} var obj = { name : ‘abc’}

  • 构造函数
    a.系统自带的构造函数 Object()
    new Object();Array();Number();Boolean();Date();
    b.自定义
    Object.create(原型)方法
    必须用 new 这个操作符,才能构造出对象构造函数必须要按照大驼峰式命名规则,但凡是构造函数就要大写,
    3.10.2 构造函数的内部原理
    前提必须要加 new,以下三步都是隐式的:
    1.在函数体最前面隐式的加上 var this = {} 空对象
    2.执行 this.xxx = xxx;
    3.隐式的返回 return this

3.10.3 包装类

  • new String();
  • new Boolean();
  • new Number();

只有原始值数字是原始值,原始值不能有属性和方法,但经过了包装类(加隐式)可以调用一些属性与方法
undefined 和 null 不可以有属性

var num = 4;
num.len = 3;
//系统隐式的加上 new Number(4).len = 3; 然后 delete
console.log(num.len);
//系统隐式的加上 new Number(4).len; 但是这个 new number 和上面的 new number
不是同一个,所以返回 undefined

而上面这些隐式的过程就是包装类。原始值要赋属性
值需要调用包装类,赋了跟没赋值是一样的。

3.10.4 原型
prototype是构造函数的属性,__ proto__是对象的属性
原型是隐式的内部属性,自己加是没有用的

  • 原型是 function 对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
  • 利用原型特点和概念,可以提取共有属性。
  • 对象属性的增删和原型上属性增删改查。
    上面通过对象(后代)改原型(祖先)是不行的,在对象里面修改,只作用给自己
    改原型都不行,增加肯定也不行。对象可以删除属性
  • 对象如何查看原型 ==> 隐式属性 proto
    浅粉色的__proto__是系统的隐式的属性,前面两个_后面两个_,可以修改,尽量不改。
    在开发的时候,如果很私人可以写成_private,告诉同事别动。
  • 对象如何查看对象的构造函数 ==> constructor。 例 person.prototype //原型(描述一种继承关系)

3.10.5 原型链

  • 原型链上属性的增删改查
    原型链上的增删改查和原型基本上是一致的。只有本人有的权限,子孙是没有的。
  • 谁调用的方法内部 this 就是谁-原型案例
  • 绝大多数对象的最终都会继承自 Object.prototype
  • Object.create(原型);
    Object.create()在括号里面只能放 null 或者 Object,其余会报错
  • 原型方法上的重写
    原型上有这个方法,我自己又写了一个和原型上同一名字,但不同功能的方法,叫做重写(同一名字的函数,不同重写方式)
    数字想用 toString 方法,要经过包装类包装 new Number(num)然后. toString
  • javascript要学多长时间 javascript学完要多久_javascript_02

  • 3.10.6 call/apply
    作用,改变 this 指向。
    区别,后面传的参数形式不同。
    (toFixed 是保留两位有效数字;Math.random()是产生一个 0 到 1 区间的开区间 随机数;向上取整 Math.ceil();向下取整 Math.floor())
  • call
    任何一个方法都可以.call
    Person.call( );括号里面可以传东西
    如果 Person.call( obj );里面的 call 让 person 所有的 this 都变成 obj
    不 new 的话,this 默认指向 window。call 的使用必须要 new
    call 的第一位参数用于改变 this 指向,第二位实参(对应第一个形参)及以后的参数都当做正常的实参,传到形参里面去借用别人的方法,实现自己的功能。
    (只能在你的需求完全涵盖别人的时候才能使用)
  • apply
    apply 也是改变 this 指向的,只是传参列表不同,第一位也是改变 this 指向的人,第
    二位,apply 只能传一个实参,而且必须传数组 argunments
    call 需要把实参按照形参的个数传进去

3.10.7 继承发展史
1.传统形式 ==> 原型链 //问题:过多的继承了没用的属性
2.借用构造函数 ==>利用 call、apply 所以不算标准的继承模式

  • (不能继承借用构造函数的原型 2)每次构造函数都要多走一个函数 ==>浪费效率)

3.共享原型(较好的继承方法)//问题:不能随便改动自己的原型

  • 在 inherit(Target,Origin)里面传进去的值是构造函数,需要大驼峰式书写,origin
    是原始的意思,让 target(目标)继承 origin
function inherit(Target,Origin){
    Target.prototype = Origin.prototype;
}

//问题:更改一个的原型会影响到另一个

4.圣杯模式

圣杯模式是在方法三的共有原型,但是在共有原型的基础上有改变。

共享原型是:son.prototype=father.prototype

圣杯模式是:另外加个构造函数 function F(){}当做中间层,然后让 F 和 father 共

有一个原型 F.prototype=father.prototype,然后 son.prototype = new F();使用原型链形成了继承关系,现在改 son.prototype 就不会影响 father.prototype

javascript要学多长时间 javascript学完要多久_javascript要学多长时间_03


联系到闭包作用:可以实现封装,属性私有化。

3.10.8 命名空间(其实就是对象)

管理变量,防止污染全局,适用于模块化开发。

javascript要学多长时间 javascript学完要多久_字符串_04


下面是现在公司最常见的方法:用闭包来解决(也可用 webpack),返回方法的调用。

init 是初始化,入口函数,入口名字。init 调用了这个函数的功能

javascript要学多长时间 javascript学完要多久_构造函数_05


3.10.9 实现链式调用模式

用 return this,就可以连续调用和执行了

javascript要学多长时间 javascript学完要多久_javascript要学多长时间_06


3.10.10 属性的表示方法(查看属性)

obj.prop 查看就用.XXXX obj[“prop”] 中括号也是访问属性的方法

用方括号来访问属性也是一样的(里面必须是字符串)

这两种基本上完全相同 obj.name → obj [ ‘name’ ]

想实现属性名的拼接,只能用方括号的形式

3.10.11对象的枚举enumeration

for in 循环(简化版 for 循环),目的是遍历对象,通过对象属性的个数来控制循环圈数,这个对象有多少属性循环多少圈,而且在每一圈时,都把对象的属性名放到 Prop里面 在枚举里面,一定要写成 obj[prop]不能加字符串

javascript要学多长时间 javascript学完要多久_javascript_07


上面就是 for in 循环,就是遍历用的。通过对象的属性个数来控制循环圈数,有多少个属性就会循环多少圈。

for(var prop in obj)在循环每一圈的时候,他会把对象的属性名放在 prop 里面。想遍历谁就 in 谁,prop 可以写别的,obj 就是我们想要遍历的对象。var XX in XX 的格式是固定的。

obj.prop 系统以后我们写的是 obj[‘prop’],系统会以为我们是在让他访问 prop这个属性,不会把 prop 当成一个变量来使用。写成 obj[prop]就可以成功访问了

  • hasOwnProperty
    hasOwnProperty 是一个方法,来判断这个对象是你自己的还是原型的, 任何一个对象里面都有 hasOwnProperty,里面是需要传参的,把属性名传进去(如 prop)。下面达到了如果不是自己的属性,是原型上的属性,就不会返回。
    一般与 for in 循环成套出现
    注明:for in 循环理论上可以返回原型和原型链上的东西,一旦这个原型链延展到了的 object.prototype 上,不会打印系统的,只会打印自带的。
  • in 操作符:很少用
    你的也是你的,你父亲的也是你的,只能判断这个对象能不能访问到这个属性,包括原型上;不是判断属性属不属于这个对象的
  • instanceof
    操作用法类似于 in,但是完全不同
    A instanceof B 的意思是 A 对象是不是 B 构造函数构造出来的;记住是:看 A 对象的原型链上有没有 B 的原型
    区别数组还是对象的方法1.constructor;2.instanceof;3.数组调用他的 toString 方法

逗号操作符,会看一眼 1,在看一眼 2,然后返回第二个

克隆

  • 浅层克隆

javascript要学多长时间 javascript学完要多久_字符串_08


把上面做一个兼容性的写法,为了防止用户不传 target(容错),给了参数就直接用,不给就当空对象

function clone(origin,target){
    var target = target || {};
    for(var prop in origin){
        target[prop] = origin[prop];
    }
    return target;
}

现在我们想实现深度克隆(只考虑数组和对象),copy 过去后,我改,但是你不会改,引用值不能直接拷贝

  • 深度克隆
function deepClone(origin,target){
    var target = target ||{},
    var toStr = Object.prototype.toString,
    var arrStr = "[object Array]";
    for(var prop in origin){
        if (origin.hasOwnproperty(prop)){
            if(origin[prop]!== "null" && typeof(origin[prop])=='object'){
                target[prop] = [];
            }else{
                target[prop] = {};
            }
            deepClone(origin[prop],target[prop])
        }else{
            target[prop] = origin[prop];
        }
    }
    return target;
}

深度克隆的步骤
1、先把所有的值都遍历一遍(看是引用值和原始值)
用 for ( var prop in obj ),对象和数组都可以使用
2、判断是原始值,还是引用值?用 typeof 判断是不是 object
1)如果是原始值就直接拷贝
2)如果是引用值,判断是数组还是对象
3、判断是数组还是对象?(方法 instanceof【看 a 的原型链上有没有 b 的原型】、
toString、constructor,建议用 toString,另外两个有个小 bug——跨父子域不行)
1)如果是数组,就新建一个空数组;
2)如果是对象,就新建一个空对象。
4、建立了数组以后,如果是挨个看原始对象里面是什么,都是原始值就可以直接考
过来了;或者,建立了对象以后,挨个判断对象里面的每一个值,看是原始值还是
引用值
5、递归

3.10.12this

  • 函数预编译过程 this —>指向 window
    如果不 new,this 指向 window
  • 全局作用域里 this —> 指向 window
  • call/apply 可以改变函数运行时 this 指向
  • obj.func(); func()里面的 this 指向 obj,谁调用这个方法,这个方法里的 this 就是指向谁

3.10 数组

3.10.1定义数组的方式
1)new Array(length/content);
2)字面量 var arr = [1,2,3,4,5];
var arr = [ ] ;数组自变量;var arr = new Array ( ) ;系统提供。两者区别就只一位数的情况。Array ( )括号里面只有一位数,就代表着长度,并且里面每一位都没有值。js 数组是基于对象的,数组是一种特殊的对象。
3.10.2数组常用的方法

  • 改变原数组(在原来数组基础上去改变)
    1)reverse,sort,push,pop, unshift, shift,
    2)splice
  • 不改变原数组
    1)forEach filter map reduce reduceRight
    2)slice concat,join—>split,toString
  • 解释:
    1.push 是在数组的最后一位添加数据,可以添加一个,也可以添加很多个
    2.pop 是剪切方法(把最后一位数剪切出去)。在 pop( )括号里面不能传参,写了会忽略
    3.unshift 是从第一位加东西
    4.shift 是从第一位开始减
    5.reverse 逆反
    6.arr.splice(从第几位开始,截取多少长度,传参在切口处添加新的数据)
    7.sort 给数组排序(按照从小到大),改变原数组。sort 按 asc 码排序的
    直接调用 arr.sort( )比的是 asc 码,要在里面填函数才可以
  • 必须写两形参
  • 看返回值 return
    1)当返回值为负数时,那么前面的数放在前面,
    2)当返回值为正数时,那么后面的数在前,
    3)为 0,不动
  • 乱序一个数组
var arr = [1,2,3,4,5,6];
arr.sort(function(){
return Math.random() - 0.5;
});

8.concat 连接, 把后面的数组拼到前面,并成立一个新的数组,不影响之前的两个数组。不能改变原数组。最后有三个数组。

9.toString 是把数组当做字符串展示出来

10.slice 从该位开始截取,截取到该位,并不改变原数组,这里也可以写负数。slice 并不改变原数组 slice 完了以后需要有东西接收,不然没有意义。slice 里面可以填 0 个参数,也可以填 1 个参数,也可以填两个参数

a.如果填两个参数,slice(从该位开始截取,截取到该位)

如 arr.slice(1,2)从第一位开始截取,截取到第二位

b.如果填一个参数,从第几位开始截取,一直截取到最后。

如果 arr.slice(1) ,从第 1 位开始截取,截取到最后一位.

c.不写参数就是整个截取数组(把类数组转换成数组的时候经常使用到)

11.join 括号里面需要用字符串形式(标准语法规定),就会用加的东西连接起数组。join 里面不传参默认用逗号连接。

join 可逆的东西:split( )是 string 字符串方法

javascript要学多长时间 javascript学完要多久_字符串_09

javascript要学多长时间 javascript学完要多久_javascript_10


split 按照什么拆分为数组。用什么拆,什么就没了,按-拆就去掉-,按 4 拆就去掉 4。

split 可以返回数组,数组可以返回字符串

3.10.3类数组

  • 可以利用属性名模拟数组的特性
  • 可以动态的增长 length 属性
  • 如果强行让类数组调用 push 方法,则会根据 length 属性值的位置进行属性的扩充。

类数组:属性要为索引(数字)属性,必须要有 length 属性,最好加上 push 方法。

3.11 报错

3.11.1try…catch
try 花括号{里面会正常执行,但是遇到 b 报错时 b 就执行不出来,后面的代码 c 就不执行了,但是外面的代码 d 还能执行}catch(e){ },这个 e 可以随便写,写 abc 都可以,也是个形参
3.11.2Error.name 的六种值对应的信息:

  • EvalError:eval()的使用与定义不一致
    //eval 是不被允许使用的
  • RangeError:数值越界
  • ReferenceError:非法或不能识别的引用数值
    //未经声明就使用,没有定义就使用
  • SyntaxError:发生语法解析错误
    // Syntax 是语法解析()
  • TypeError:操作数类型错误
  • URIError:URI 处理函数使用不当
    //引用地址错误

3.11.3es5.0 严格模式
浏览器是基于 es3.0 和 es5.0 的新增方法使用的。
如果两种发生了冲突,就用 es3.0。
es5.0 严格模式是指 es3.0 和 es5.0 产生冲突发部分就是用 es5.0,否则就用 es3.0。

  • “use strict” ;不再兼容 es3 的一些不规则语法。使用全新的 es5 规范。两种用法:
    1.全局严格模式
    2.局部函数内严格模式(推荐)
    就是一行字符串,不会对不兼容严格模式的浏览器产生影响。
    不支持 with,arguments.callee,function.caller,变量赋值前必须声明,局部 this必须被赋值(Person.call(null/undefined) 赋值什么就是什么),拒绝重复属性和参数
    caller函数对象的一个属性,指向调用当前函数的函数。比如 A() 调用 B(), 则在B()中 B.caller 指向A()。
    callee是arguments对象的一个属性,指向 arguments 对象的函数,即当前函数。在例子中是XX。
    with(){ }可以改变作用域链。{}里面的代码会按照正常顺序执行,但是如果在括号里面添加了对象,就会把对象当做 with 要执行的代码体的作用域链的最顶端(最直接的最近的 AO)。

四.DOM

4.1什么是DOM

1.DOM — > Document Object Model(文档对象模型)
2.DOM 定义了表示和修改文档所需的方法(对象、这些对象的行为和属性以及这些对象之间的关系。)DOM 对象即为宿主对象,由浏览器厂商定义,用来操作 html和 xml 功能的一类对象的集合。也有人称 DOM 是对 HTML 以及 XML 的标准编程接口
dom 不能改变 css 样式表,可以间接改变行间样式的 css

4.2DOM基本操作(大部分都是类数组)——方法类操作

document 代表整个文档(如果给 html 标签上面再套一层标签就是 document)
4.2.1对节点的增删改查
注意哪怕整个文档只有一个 demo,也要加[0],不然选出来的就是一个组

  • document.getElementById() //元素 id 在 Ie8 以下的浏览器,不区分 id 大小写,而且也返回匹配 name 属性的元素,通过 id 标识我们来选择这个元素,一一对应
  • getElementsByTagName() //标签名,这是一个类数组,最主流的用法,经常用
  • getElementsByName(); //IE 不支持需注意,只有部分标签 name 可生效(表单,表单元素,img,iframe),不是在所有的浏览器都能用——开发一般不用
  • .getElementsByClassName() // 类名 ->缺点: ie8 和 ie8 以下的 ie 版本中没有,可以多个 class 一起,不是所有浏览器都能用
  • .querySelector() // css 选择器,只能选一个,在 ie7 和 ie7 以下的版本中没有
  • .querySelectorAll() // css 选择器,全选,选一组,在 ie7 和 ie7 以下的版本中没有

querySelectorAll()和.querySelector()选出来的元素不是实时的(是静态的),所以一般不用,其他的再怎么修改,跟原来的没有关系

4.3DOM基本操作——非方法类操作

4.3.1遍历节点树

  • parentNode → 父节点 (最顶端的 parentNode 为#document);
  • childNodes → 子节点们(直接的节点数)节点包括文本节点,属性节点
  • firstChild → 第一个子节点
  • lastChild → 最后一个子节点
  • nextSibling →后一个兄弟节点
  • previousSibling → 前一个兄弟节点

4.3.2节点的类型
元素节点 —— 1
属性节点 —— 2 (基本没用,)
文本节点 —— 3
注释节点 —— 8
document —— 9
DocumentFragment —— 11
后面的数字是调用 nodeType 返回的数字
规范化

4.3.3基于元素节点树的遍历(不含文本节点)

  • parentElement -> 返回当前元素的父元素节点 (IE 不兼容)
  • children -> 只返回当前元素的元素子节点
  • node.childElementCount === node.children.length 当前元素节点的子元素节点个数(IE 不兼容)——基本不用,因为与 length 相等
  • firstElementChild -> 返回的是第一个元素节点(IE 不兼容)
  • lastElementChild -> 返回的是最后一个元素节点(IE 不兼容)
  • nextElementSibling / previousElementSibling ->返回后一个/前一个兄弟元素节点(IE 不兼容)

除 children 外,parentElement、node.childElementCount、firstElementChild、lastElementChild、nextElementSibling、 previousElementSibling 在 ie9 及以下不兼容。真正常用的就是 children,兼容性好

4.3.4 每一个节点的四个属性

  • nodeName元素的标签名,以大写形式表示,只读,不能写
  • nodeValue Text 文本节点或 Comment 注释节点的文本内容,可读写
  • nodeType(最有用)该节点的类型,只读返回这个 div 的所有的元素节点
  • attributes Element 节点的属性集合
    属性名不能改,属性值可以改,但是我们一般不用这种方法
    我们一般用 getAttribute 和 setAttribute 去取。节点的一个方法

Node.hasChildNodes();——他有没有子节点,返回值是 true 或 false

4.3.5 DOM接口

dom 结构树代表的是一系列继承关系

javascript要学多长时间 javascript学完要多久_javascript要学多长时间_11


document 继承自 HTMLDocument.prototype。HTMLDocument.prototype 继承自 Document.prototype

DOM 结构树中,Node 也是构造函数,comment 是注释HTMLDocument 和 HTMLElement 实际上并列了对应的XML,但是因为不用了 XML就省略了。HTMLHeadElement 就是 head 标签,其余类推。

4.4 DOM基本操作

4.4.1常用操作注意

  • getElementById 方法定义在 Document.prototype 上,即 Element 节点上不能使用。
  • getElementsByName 方法定义在HTMLDocument.prototype 上,即非 html 中的document 以外不能使用(xmldocument,Element)
  • getElementsByTagName 方法定义在 Document.prototype 和 Element.prototype 上
  • HTMLDocument.prototype 定义了一些常用的属性,body,head,分别指代 HTML 文档中的标签。
  • Document.prototype 上定义了 documentElement 属性,指代文档的根元素,在 HTML文档中,他总是指代元素
  • getElementsByClassName、querySelectorAll、querySelector 在 Document,Element 类

4.4.2 增
document.createElement(); //增加或创建元素节点(标签)——常见
document.createTextNode(); //创建文本节点
document.createComment(); //创建注释节点
document.createDocumentFragment(); //创建文档碎片节点
4.4.3 插——剪切操作
PARENTNODE.appendChild(); 可以理解成.push
PARENTNODE.insertBefore(a, b);一定是 div 先 insert a,before b(剪切效果)
4.4.4 删
parent.removeChild(); //返回移除子元素,就是被剪切出来了
child.remove(); //自尽,完全删除
4.4.5 替换
parent.replaceChild(new, origin); //用新的 new 去置换旧的 origin
4.4.6Element 节点的一些属性和方法

  • 属性:
    innerHTML ==> 可取,可写,可赋值
    innerText ==> 可取,可赋值 (老版本火狐不兼容) / textContent(火狐使用这个,老版本 IE 不好使)
  • 方法:
    ele.setAttribute(“属性”,“值”) //设置
    ele.getAttribute(“属性”); //取这个值

4.6Date()

就是一种对象,是系统提供好的
var date = new Date()大写的 Date 是系统提供的一个构造函数,通过 new Date 的方法会给我们返回一个对象,这个对象就是一个日期对象。日期对象有很多属性和方法。小的 date 代表此时此刻的时间。用小的 date 调用方法,如 date.getDate( )
4.6.1Date对象方法

  • Date() 返回当日的日期和时间。
  • getDate() 制造出对象,从 Date 对象返回一个月中的某一天 (1 ~ 31)。
  • getDay() 今天是一周的第几天,如果是 2 是星期二,但是是指三天(第一天是周日,也就是 0)。从 Date 对象返回一周中的某一天 (0 ~ 6)。
  • getMonth() 一月份返回值是 0,从 Date 对象返回月份 (0 ~ 11)。
  • getFullYear() 从 Date 对象以四位数字返回年份。
  • getYear() 已废弃。请使用 getFullYear() 方法代替。
  • getHours() 返回 Date 对象的小时 (0 ~ 23)。
  • getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。
  • getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。
  • getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。
  • getTime() 最有用 返回 1970 年 1 月 1 日(纪元时刻)至今的毫秒数。经常用于项目的计算时间。获取时间戳
  • setDate() 设置 Date 对象中月的某一天 (1 ~ 31)。
  • setMonth() 设置 Date 对象中月份 (0 ~ 11)。
  • setFullYear() 设置 Date 对象中的年份(四位数字)
  • setYear() 请使用 setFullYear() 方法代替。
  • setHours() 设置 Date 对象中的小时 (0 ~ 23)。
  • setMinutes() 设置 Date 对象中的分钟 (0 ~ 59)。
  • setSeconds() 设置 Date 对象中的秒钟 (0 ~ 59)。
  • setMilliseconds() 设置 Date 对象中的毫秒 (0 ~ 999)。
  • setTime() 以毫秒设置 Date 对象。机械之间交换时间
  • toSource() 返回该对象的源代码。
  • toString() 把 Date 对象转换为字符串。
  • toTimeString() 把 Date 对象的时间部分转换为字符串。
  • toDateString() 把 Date 对象的日期部分转换为字符串。
    在控制台调用 date.getSeconds 就是 date 创建时间的毫秒数,是静止的,不是动态的。
    这个 date 对象记录的是出生的那一刻的时间,不是实时的
    4.6.2js定时器
  • setInterval(); //注意:setInterval(“func()”,1000);定时循环器
  • javascript要学多长时间 javascript学完要多久_数组_12

  • 如果先定义 1000 毫秒,在后面改成 2000 毫秒,程序仍按 1000 毫秒执行,因为他只识别一次,不能通过改变 time 改变 setInterval 的快慢。
    setInterval 计算时间非常不准
    注意:setInterval();是 window 的方法,在全局上就算不写 window. setInterval();他也会上全局的 GO 里面查找,所以不写 window.也行。
    每一个 setInterval();都会返回一个数字,作为唯一的标识,有唯一标识就可以把他清除掉(利用 clearInerval 清除)
  • clearInterval(); //能让 setInterval 停止
    一般写了 setInterval 就要写 clearInterval
  • setTimeout(); //正真的定时器,隔了一段时间后再执行(起推迟作用),并且只执行一次。返回一个数字做唯一标识。标识不会重叠。
  • clearTimeout(); //清除 setTimeout();让他停止执行
  • javascript要学多长时间 javascript学完要多久_构造函数_13

  • 这种写法,setTimeout();还没执行就被清除了,就执行不了

setInterval();setTimeout();clearInterval();clearTimeout();这四个都是全局对象,都是window 上的方法,内部函数 this 指向 window

4.7 DOM/BOM基本操作

4.7.1 查看滚动条的滚动距离

  • window.pageXOffset 横向/pageYOffset 纵向滚动条
    IE8 及 IE8 以下不兼容(IE9 部分兼容)IE9 以上能用
  • IE8 及 IE8 以下的使用方法
    1)document.body.scrollLeft/scrollTop——求横向距离和纵向距离
    2)document. documentElement.scrollLeft/scrollTop
    上面两个兼容性比较混乱,其中一个有值,另外一个的值一定是 0。这两个最好的用法是取两个值相加,因为不可能存在两个同时有值
    如 document.body.scrollLeft + document. documentElement.scrollLeft
  • 封装兼容性方法(哪个浏览器都好用),求滚动轮滚动距离 getScrollOffset()——求滚动条的位置
function getScrollOffset(){
    if(window.pageXOffset){
        return{
            x : window.pageXOffset,
            y : window.pageYOffset
        }
    }else{
        return{
            x : document.body.scrollLeft + document.documentElement.scrollLeft,
            y : document.body.scrollTop + document.documentElement.scrollTop
        }
    }
}

4.7.2 查看视口的尺寸
可视区窗口就是编写的 html 文档可以看到的部分,不含菜单栏、地址栏、控制台

  • window.innerWidth/innerHeight 可视区域的宽高 (加上 滚动条宽度 / 高度)IE8 及 IE8 以下不兼容 //w3c 标准方法
    注意渲染模式:
    1 标准模式:<!DOCTYPE html>是 html5 的(在 emmet 插件下 html:5 就出来了)
    2 怪异/混杂模式:试图去兼容之前的语法,去掉<!DOCTYPE html>这一行即可开
    启(向后兼容)
    2、document.documentElement.clientWidth/clientHeight
    标准模式下,任意浏览器都兼容 client 是客户端的意思
    3、document.body.clientWidth/clientHeight
    适用于怪异模式下的浏览器
    4、封装兼容性方法,返回浏览器视口尺寸 getViewportOffset()

document.compatMode 是用于判断是怪异模式还是标准模式的
"CSS1Compat"标准模式 ''BackCompat"怪异模式向后兼容

function getViewportOffset(){
    if(window.innerWidth){
        return{
            w : window.innerWidth,
            h : window.innerHeight
        }
    }else{
        if(document.compatMode ==="BackCompat"){
            return {
                w : window.innerWidth,
                h : window.innerHeight
            }
        }else{
                return {
                    w : document.documentElement.clientWidth,
                    h : document.documentElement.clientHeight
                }
            }
        
        }
    }
}

4.7.3 查看元素的几何尺寸

  • domEle.getBoundingClientRect(); //这是 es5.0 的方法,但是只用了解
  • 兼容性很好
  • 该方法返回一个对象,对象里面有 left,top,right,bottom 等属性。left 和 top 代表该元素左上角的 X 和 Y 坐标,right 和 bottom 代表元素右下角的 X 和 Y 坐标
  • height 和 width 属性老版本 IE 并未实现在老版本的 ie 里面,利用右侧边减左侧面解决
  • 返回的结果并不是“实时的”

4.7.4 查看元素的尺寸
dom.offsetWidth,dom.offsetHeight
求得值是包括 padding 的
4.7.5 查看元素位置

  • dom.offsetLeft, dom.offsetTop
    对于无定位父级的元素,返回相对文档的坐标。
    对于有定位父级的元素,返回相对于最近的有定位的父级的坐标。(无论是 left 还是margin-left 等都是距离。 )
  • dom.offsetParent
    返回最近的有定位的父级,如无,返回 body, body.offsetParent 返回 null这个方法能求有定位的父级

4.7.6 让滚动条滚动

  • window 上有三个方法 scroll(), scrollTo(),两个功能一样,scrollBy();累加滚动距离
    scroll(x,y), scrollTo(x,y),功能是一样的,里面能填两个参数
    scroll(x 轴滚动条的距离,y 轴滚动条的距离),里面的 xy 可以填负数
    scrollBy(x,y);是累加滚动距离,填负数就往上滚动
    2、三个方法功能类似,用法都是将 x,y 坐标传入。即实现让滚动轮滚动到当前位置。
    3、区别:scrollBy()会在之前的数据基础之上做累加。
    eg:利用 scrollBy() 快速阅读的功能

五.学习心得

js是前端学习的重中之重,内容很多,入门虽然简单但是常常会忽视掉一些底层的原理。学习js一定要注意底层原理,开发中可能一个不小心就给调试带来很大的麻烦。在学习的时候要求精,不要一味追求速度。