1.JavaScript的由来?
JavaScript诞生于1995年,当时的主要目的是处理由以前服务器语言负责的一些没有填写的必填域,是否输入了无效的值。在web日益流行的同时,人们对客户端脚本语言的需求也越来越强烈,那时绝大多数因特网用户使用的速度仅为28.8kbit/s的猫上网,但网页的大小和复杂性却不断增加,未完成简单的表单验证而与服务器交换数据只会加重用户和服务器的负担。
1995年2月 计划在Netscape Navigator2开发名为LiveScript的脚本语言,同时在浏览器和服务器中使用,为了赶在发布日期前完成LiveScript开发,Netscape和sun公司建立了一个开发联盟,在Netscape Navigator2发布的前夕,为了搭上媒体上热炒的java顺风车,临时把LiveScript改名为JavaScript。在Navigator3发布不久,ie3就加入了名为JScript的 JavaScript的实现。这意味着有两个不同的JavaScript版本:javascript,jscript.当时并没有标准规定JavaScript的语法和特性。
1997年,JavaScript1.1 为蓝本的建议被提交给了ECMA(European ComputerManufacturersAssociation欧洲计算机制造商协会)。定义了ECMAScript新脚本语言的标准(ECMA-262)。第二年ISO/IEC(International Organization for Standardization and International Electrotechnical Commission,国标标准化组织和国际电工委员会)也采用了ECMAScript作为标准(ISO/IEC-16262),自此浏览器开发商就致力于将ECMAScript作为各自JavaScript实现的基础。
2.什么是JavaScript?
JavaScript 是一个编程语言,允许用户在浏览器页面上完成复杂的事情。浏览器页面并不总是静态的,往往显示一些需要动态更新的内容,交互式地图,动画,以及视频等。一个完整的JavaScript 包括核心 (ECMAScript) ,应用程序编程接口即 API ( 比如DOM(Document Object Model), BOM(Browser Object Model)) ,以及其他第三方 API 。JavaScript与 HTML 、 CSS 一同配合共同完成一个复杂页面的显示。
3.特点
1.弱类型语言
- eg:对比java这种强类型语言以下就会出现报错
- 而JS并不会出现以上情况,而是会输出hello
2.脚本语言:本身具有逻辑和行为能力
3.解释性语言:被内置于浏览器或者NodeJS平台中的JS解析器解析执行,执行前无需编译
4.从上到下按照解析顺序执行依次执行 (注意:代码书写顺序不一定是解析顺序)
eg:
- 代码顺序 (有问题,但是在js中可以正常运行而不会报错)
- 解析顺序:
- 执行顺序:
优先解析函数声明,然后解析使用var操作符声明的变量
5.JS对大小写敏感
- eg:
4.语法
1.如何声明一个变量?(变量的声明)
1>标识符的声明
标识符:用来标识一个东西
- 1.由字母、数字、下划线以及$组成
- 2.不能以数字开头
- 3.建议使用驼峰式命名(从第二个单词开始,首字母大写)
- eg: var firstNameAndLastName='张三';
- 4.不能使用关键字和保留字
- 关键字:在js中具有特殊意义的字符
- 保留字:未来有可能成为关键字的字符
2>变量的声明
- es5:
- 1.var a; //声明一个a变量但不赋值 --->node 2.js ---》值为 undefined
- 2. var b="world"; //声明的同时赋值
- 3. c='hello'; //变量声明并赋值(同2表示)
- 4.var a=2,b=3,c=4; //同时声明多个变量
- es6:
- let:
- 使用let声明的变量,只能声明一次(不能重复声明)
- 不能进行变量的提升
- 局部变量,只在当前作用域内有效
- const:
- 一般用来声明常量,一旦声明,不可修改
- 使用const声明的常量,只能声明一次,不能重复声明
- 局部变量,只在当前作用域内有效
- 不能解析提升改变量
- 如果常量值为引用数据类型(存在于堆区,使用时需要使用到引用地址),只要引用地址不变,即可修改内部属性
2.注释
①单行注释: // 注释内容
- 可以嵌套使用
②多行注释: /* 注释内容*/
- 不能嵌套使用
3.语句
- 每一行语句结束时建议使用 ;结尾
- var a=10;
5.JS的使用
1.嵌入在html标签内部
<script></script>标签2.外部引入脚本
script标签:src属性
创建一个js文件,以.js为文件后缀名
3.node
1》创建一个js文件,以.js为文件后缀名
2〉执行 node test.js注意:
使用了src属性的script标签,内部的代码会被解析器忽略
6.局部变量和全局变量
1.全局变量和局部变量
- 全局变量:指在整个js内都能被访问到的变量
- 局部变量:只能在代码块内部(特定区域)使用,外部无法使用的变量
2.如何声明全局变量和局部变量?
局部变量:
- 1》使用const声明变量
- 2》使用let声明变量
- 3》使用了var操作符并声明在函数内部时候为局部变量
7.数据类型
- 共有6种数据类型(5种基本数据类型(简单数据类型)+1种引用数据类型(复杂数据类型))
1》基本数据类型
①undefined:未定义型数据类型
②null:空引用数据类型(即将指向堆区,但是此时没有指向)
eg:var a=null; //值为null,数据类型object
- undefined派生自null
- 比较符:
- null==undefined:true;
- null===undefined:flase
③Number:数值类型:
- 10 整数
- 10.3 浮点数
- 011 二进制
- 0xa... 16进制
- NaN:Not a Number
- isNaN方法:判断--> 是不是 不是 一个数?
- isNaN(a)
- 表示:a是不是 不是一个数
- 当a不是一个数时,返回true;
- 当a是一个数时,返回false;
- Infinity:无穷
- isFinity方法:是不是一个无穷数?
- isFinity(a):a是否为无穷数
- flase:a是一个无穷数
- true:a不是一个无穷数
④boolean类型 (只有两个值)
- flase
- true
- eg:
- var a=true; ---》 true boolean
- var a=flase;
⑤string:字符串类型
- 使用单引号或者双引号包裹的字符或者``反引号包裹
- json字符串
2》引用数据类型 (在堆区存储)
object
- 子类型:
- function、array、date...
- 共有的属性和方法
- constructor
- toString() //将当前变量转换为字符串类型,不同 类型调用toString方法不同,结果不同
- valueOf() //返回变量的原始值
8.数据类型转换(主要是基本数据类型间的转化)
- null和undefined不参与转换(Number、boolean、string之间转换)
①Number (**--->Number)
1》Number转换函数 : Number()
- Number(a);
- null :转换结果为0
- undefined:转换结果为NaN
- true:转换结果为1
- false:转换结果为0
- " " :转换结果为0
- "hello" :转换结果为NaN
- " 10" :转换结果为10
- "10.3" :转换结果为10.3
- "10l" :转换结果为NaN
- "+10" :10
- "a10":NaN
- 测试代码:如下
- var a=null;
console.log(a);
console.log(typeof a);
console.log(Number(a));
console.log(typeof Numbe(a));- 结果表示: 输出a的值为null
输出的值的类型为object类型
Number()转换函数使用后输出的转换结果为0
转换结果的数据类型为Number数据类型
2》parseInt(a): 解析整型
- null :转换结果为NaN
- undefined:转换结果为NaN
- true:转换结果为NaN
- false:转换结果为NaN
- " " :转换结果为NaN
- "hello" :转换结果为NaN
- " 10" :转换结果为10
- '10.3' :转换结果为10
- '10.9':10
- "10l" :转换结果为10 (从前往后依次解析,返回可以解析的,舍弃不能解析的)
- "+10" :10
- "a10":NaN
- eg:测试parseInt(undefined ) (同以上代码步骤结果如下)
3》parseFloat(a):解析浮点型
- null :转换结果为NaN
- undefined:转换结果为NaN
- true:转换结果为NaN
- false:转换结果为NaN
- " " :转换结果为NaN
- "hello" :转换结果为NaN
- " 10" :转换结果为10
- '10.3' :转换结果为10.3
- '10.9':10.9
- "10l" :转换结果为10 (从前往后依次解析,返回可以解析的,舍弃不能解析的)
- "+10" :10
- "a10":NaN
②boolean (**--->boolean)
Boolean(a):
- null :转换结果为false
- undefined:转换结果为 false
- 0:转换结果为false
- 非0:转换结果为true
- 空字符串:
- " " :转换结果为false
- 非空:
- "hello" :转换结果为true
- " 10" :转换结果为true
③String(**--->String)
- 1》String(a): //String转换函数
- null: 转换结果为"null"
- undefined:换结果为"undefined"
- 直接在变量值之外加单引号或者双引号
- 2》toString(num)转换方法
- a.toString(num) //num:进制数
- null和undefined没有toString()
- a.toString(2) //要使用,前面对应的a最好是一个可以转换为(二)进制数的
- true . toString():转换结果为"true"
- 10. toString():转换结果为"10"
- 10. toString(2):转换结果为"1010"
9.值传递问题
- 基本数据类型在进行值传递时候传递的是值,引用数据类型在进行值传递时候传递的是引用地址
1.基本数据类型的值传递:
- 错误:
- 正确:
2.引用数据类型的值传递
- 问题:
- 输出结果:均为terry
- 运行过程解析
- 引用数据在堆区存储,在栈区存放的是内存为其分配的一个引用地址,当obj1赋值给obj2时候,将其引用地址也给了obj2,也就是obj1和obj2的引用地址一样,都指向堆区1001地址的数据,如果obj2将其中的属性(eg:name='terry';)改变后,obj1.name再输出时候,输出的是改变后的值,同理,obj1将内部属性改变,输出obj2.name时候,也是改变后的terry