JavaScript介绍[历史 背景 特点],运算符,数组,对象
JavaScript介绍
- 认识JavaScript
- JavaScript作用是和网页进行交互的
- JavaScript是一门编程语言
- 编程语言的发展史:
- 机器语言
- 汇编语言
- 高级语言:avaScript/c/c++
- JavaScript历史
- 诞生背景:1995年网景公司Eich,Scheme,发明的JavaScript
- 微软公司:JScript
- 1996年网景公司向ECMA(欧洲计算机制造商协会)提交了提案: ECMA指定这门语言的标准
- 1997年ECMA指定标准: ECMAScript
- JavaScript只是ECMAScript一种实现:
- ==JavaScript: JavaScript + DOM + BOM==
- JavaScript特点
- 解释性语言
- 读取一行,解释一行,执行一行
- 另外一种是编译型语言
- 动态类型语言
- 在运行阶段可以动态修改变量的类型
- var name=”why”
- name=123
- JavaScript目前可以做哪些工作
- 网页特效
- 服务端开发(node.js)
- 命令行工具
- 桌面程序
- APP(Cordova)
- 控制硬件(Ruff)
- 游戏开发(cocos2d-js)
- 注意事项
- script标签时双标签不能写成单标签
- 省略type属性:,
1
<script>标签中会使用 type="text/javascript"。现在可不写这个代码了,因为JavaScript 是所有现代浏览器以及 HTML5 中的默认脚本语言
- 加载顺序
- 作为HTML文档内容的一部分,JavaScript默认遵循HTML文档的加载顺序,即自上而下的加载顺序
- 推荐将JavaScript代码和编写位置放在body子元素的最后一行
- JavaScript代码严格区分大小写
- 解释性语言
- JavaScript填写位置
- HTML元素中
- script标签里面
- 外部引入js文件
- JavaScript注释
- 单行注释
- 多行注释
- 文档注释
- 浏览器的交互方式
- 交互方式一:浏览器弹出窗口
- 交互方式2:在控制台打印内容,输出内容多个之间通过逗号隔开
- 交互方式3:DOM操作
- 交互方式4:接收用户输入的内容
1
2
3
4
5
6
7
8
9// 1.交互方式一:浏览器弹出窗口
alert('Hello World')
// 交互方式2:在控制台打印内容,输出内容多个之间通过逗号隔开
console.log('hello 你好',"你好",18)
// 3.交互方式3:DOM操作
document.write("<h2>Hello HTML</h2>")
// 4.交互方式4:接收用户输入的内容
var age = prompt("请输入你的年龄")
console.log("你的年龄是:",age)
- 变量的命名方式
- 变量的声明:在一个JavaScript中声明变量使用关键字var(后续学习ES6还有let,const声明方式)
- 这个过程也可以分开操作
- 同时声明多个变量
- 变量的命名规则
- 第一个字符必须是一个字母、下划线( _ )或一个美元符号( $ )
- 其他字符可以是字母、下划线、美元符号或数字。
- 不能使用关键字和保留字命名:常用的关键字和保留字查询地址
- 变量名命名规范(建议遵守)
- 多个单词使用驼峰标识
- 赋值=两边都加上空格
- 一条语句结束后都添加分号
- 定义变量保存两个数字并将变量的数字进行交换
- 1.使用临时变量
- 2.不使用临时变量
1
2
3定义变量保存两个数字并将变量的数字进行交换
1.使用临时变量
2.不使用临时变量
- JavaScript常见的基本类型
- 数值型(Number)
- 数字的表示方式:十进制,二进制,八进制
- 数值表示范围:
- NaN,即非数值(Not a Number)是一个特殊的数值,JS中当对数值进行计算时没有结果返回,则返回NaN
- isNaN,用于判断是否不是一个数字。不是数字返回true,是数字返回false。
- 数值型(Number)
1 | var n10 = 10 |
- 字符串型(String)
- 字符串的表示可以使用单引号也可以使用双引号。
- 转义字符:\’ \” \t制表符 \n换行符,\反斜杠,\b退格符.\r回车符四个的用法
- 获取字符串的长度:length属性
1
2无括号,length是属性
str.length
- 布尔型(Boolean)
- 两个取值: true/false
- 空类型(Null)
- Null类型也是只有一个值:null
- 通常对象在回收时设置为null
- 未定义型(Undefined)
- 只有一个值undefine
- 在使用 var 声明变量但未对其加以初始化时,这个变量的值就是 undefined
- typeof对没有初始化和没有声明的变量都会返回undefined
- Null和Undefined的关系:
- undefined值实际上是由null值衍生出来的,所以如果比较undefined和null是否相等,会返回true
- 但是转化成数字时,undefined为NaN,null为0
- typeof可以查看变量类型
1
2
3两种写法都可以
console.log(typeof str)常用
console.log(typeof(str))- ==变量存储的本质==
- 内存的分类:栈空间和堆空间
- 基本数据类型分配在栈空间
- 引入数据分配在堆空间
(浏览器数据类型加载在内存中的堆空间和栈空间)- 数值类型的转换
- Number(其他类型)
- parseInt(数值,radix基数):将string->整数
- parseFloat():将string->浮点数
- 转换成字符串类型
- toString()方法格式:变量.toString()
- 只能转换数值类型和布尔类型
- String(变量): 可以转换所有类型
- 字符串拼接:格式:变量+””
- 转换成boolean类型
- 转成false的五种:””,0,undefined,null,NAN
- 其他均为true
JavaScript运算符
- 算术运算符/
- 赋值运算符/
- 关系(比较)运算符/
- ‘===’表示全等,他和’==’基本一致,不过’==’在判断两个值时会进行自动的类型转换,而’===’不会。
- 比如”123”==123 会返回true,而”123”===123会返回false;
- 除了!=以外,JS中还提供了!==
- !==也不会进行自动类型转换,比如”123”!=123 会返回false,而”123”!==123会返回true;
- 逻辑运算符
- 逻辑与运算符可以应用于多个运算符,且不一定为boolean值
- 对于非布尔的运算,会先转换为布尔值
- 逻辑与和逻辑或的特殊用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/*
1.逻辑与的特殊用法:多个条件都为true
先判断存在不存在,存在则进行后面函数的调用,就不会出现报错的情况
与运算的特殊用法:多个条件都为true
有一个条件为falsename后续将不再判断
*/
var name = "ftt";
// 对象中存放的是键值对
var info = {
name: "ftt",
age: 18,
height: 1.65,
// eating: function() {
// console.log("吃东西");
// }
};
info.eating && info.eating()
/*
2.逻辑或的特殊用法:只要有一个条件为true
一旦遇到条件为true.那么后面的条件将不再执行
*/
var message = info.name || info.age || info.height
console.log(message)- 三元运算符
- 格式:表达式1 ? 表达式2 : 表达式3
- 满足表达式1执行表达式2,否则执行表达式3
- switch分支语句
- 断点调试(debug)
- 通过打印到控制台
- 开启断点调试的两种方式
- 找到自己的源代码,在其中打断点
- 在代码中写上debugger
JavaScript数组
- 数组
- JavaScript中的数组我们可以通过字面量的方式创建:[]
- []中存放一组数据
- 虽然JavaScript支持在数组中存放不同的数据类型,但是开发中建议存放相同的类型
- 数组常见操作
- length属性
- 获取数组某个位置通过索引值
- 在JavaScript中获取一个不存在的索引值,不会报错,结果为undefined
- JavaScript中的数组我们可以通过字面量的方式创建:[]
- 冒泡排序
- JavaScript主要分为:ES(ECMAScript),BOM,DOM
- 对象的分类:
- 内建对象
- ES6标准中定义的对象,在任何的ES的实现中都可以使用
- 比如:Math String Number Boolean Function Object
- 宿主对象
- 由JS的运行环境提供的对象,目前来讲主要由浏览器来提供
- 比如:BOM,DOM
- 自定义对象
- 由开发人员自己创建的对象
- 内建对象
- 对象的基本操作
- 创建:构造函数专门用来创建对象的函数,通过new创建的函数都叫做构造函数,通过typeof查看属性
- 两种方式:1.通过new构造函数创建
- 直接通过大括号中的键值对进行创建var obj2 = {
};==使用奇怪的名字,属性名要添加双引号==name: "ftt", age: 18, gender: "女",
- 向对象中添加的值称为属性,属性的添加格式:对象.属性名 = 属性值
- 修改属性:对象.属性名 = 新属性值
- 通过in字符查看对象中属性的存在格式:”属性名” in 对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/*
对象的声明:
1.通过构造函数new进行创建
*/
obj = new Object();
obj1 = new Object();
// 2.特殊的属性名通过中括号进行创建[] 更加灵活,通过传递变量进行属性的读取
obj["123"] = "你好";
console.log(obj["123"]);
var n = "123";
console.log(obj[n]);
// js对象的属性值可以是任意的值
obj.test = obj1;
obj.name = "ftt";
console.log(obj.test);
// 通过in字符查看对象中属性的存在格式:"属性名" in 对象
console.log("test" in obj);
- 创建:构造函数专门用来创建对象的函数,通过new创建的函数都叫做构造函数,通过typeof查看属性
- 基本数据类型和引数据类型
- 基本数据类型的值是无法修改的,不可变的,基本数据类型比较的是==值==的比较,也就是两个变量的比较;保存在栈中
- 引用数据类型:保存在内存中的对象;当一个变量是一个对象时,实际上变量中保存的并不是对象本身,而是对象的==引用==;当从一个变量向另一个变量复制引用类型的值时,会将对象的引用复制到变量中,并不是创建一个新的对象。这时,两个变量指向的是同一个对象。因此,改变其中一个变量会影响另一个。
- 堆和栈
- 函数也是对象,可以存储东西
- 函数是由一系列子程序组成
- 函数可以封装一些可执行的代码,拥有普通对象的功能
- 函数需要调用才能执行:函数名()
- 函数通过typeof属性查看时显示object类型
- 创建函数两种方式:
- 通过构造函数创建(开发中不用)var fun = new Function(“console.log(‘Hello World’);”);
- 使用函数声明创建函数:function 函数名(参数1,…){语句}
- 使用函数表达式的方式创建函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 创建函数1(通过构造函数,一般不使用)
var fun = new Function("console.log('Hello World');");
// 2.创建函数通过声明的方式
function fun1 (){
console.log("我是函数");
alert("哈哈哈");
document.write("dkfsoj;ijs;diof");
}
// 3使用函数表达式:匿名表达式,没有函数名
var fun3 = function(){
console.log("我是匿名函数");
}
// 调用函数
fun();
fun1();
fun3();
- 通过构造函数创建(开发中不用)var fun = new Function(“console.log(‘Hello World’);”);
- 函数参数:
- 调用函数时解析器不会检查实参的类型和个数
- 当实参的个数少于形参时
- 函数返回值
- 函数中通过return返回值;
- 不写return时,返回undefined
- return可以返回任何类型的值
- 实参可是是任意数据类型(数值,对象,函数等)
- sayHello和sayHello()的区别:
- sayHello是一个对象,
- sayHello()是函数调用,传入的是返回值
- sayHello和sayHello()的区别:
- 立即执行函数
- 立即执行函数只会执行一次
- 两种不同的写法:立即执行函数需要加括号()才不会报错,将他们看成一个整体
1
2
3
4
5
6
7
8立即执行函数:只会执行一次 没有参数的执行函数,注意需要加()才不会报错,若要立即执行只需要在最后加上()
(function(){
console.log("我是立即执行函数");
})();
// 有参数的立即执行函数
(function(a,b){
console.log(a+b);
})(123,345);
- 对象的属性可以是任意的数据类型行(函数)
1
2
3obj.test;//是一个函数
obj.test();//1,调对象的方法
fun1();//2,调函数,1,2只是名称上的区别 - 函数的属性查看方法:
- 对象.属性名
- 对象[变量名]更加灵活方便
- 通过枚举的方式遍历对象的属性
- obj[n]这里的n是变量所有只能通过变量的方式查看属性名
1
2
3
4
5
6
7
8
9
10// 通过for (var n in obj)枚举对象中的属性
var obj = {
name:"猪八戒",
age:17,
gender:"男",
address:"高老庄"
}
for (var n in obj) {
console.log(n + " "+ obj[n]);
}
- obj[n]这里的n是变量所有只能通过变量的方式查看属性名
- 作用域:
- 全局作是最外围的执行环境,在web浏览器中,全局执行环境被认为是windows对戏哪个,因此所有的全局变量和函数都作为windows对象啊的属性和方法创建
- 每个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的变量和函数定义也随之销毁
- 在内部环境可以读取外部环境的变量,反之不行.
- 变量的生声明:
- 1.变量的声明:使用var关键字声明的变量会在所有代码执行之前就声明(但不会赋值),所以即使在声明之前调用会显示undefined,不用var声明则会直接报错;
- 2.函数的声明:
- 使用函数声明形式创建的函数function 函数名(){}会在所有代码执行之前就被创建,所以我们可以再函数声明之前就调用
- 使用函数表达式创建的函数,不会被声明提前,不能提前进行条用
1
2
3
4
5
6
7
8
9
10
11
12
13console.log(a);//undefined
var a = "123";
var b = "hahah ";
console.log(a);//123
fun();//执行
fun1();//报错显示不是function,var声明的为赋值的默认为undefined
function fun() {
console.log('我是声明函数声明的function函数');
}
var fun1 = function() {
console.log("我是函数表达式声明的函数")
}
- 函数作用域
- 调用函数时创建函数作用域,函数执行完毕,函数作用域销毁
- 每调用一次函数就会创建新的作用域,他们之间是互相独立的
- 在函数作用域中可以访问全局作用域,反之不行
- 在函数作用域中操作一个变量时现在自身作用域中寻找,没有则向上一级寻找,若全局作用域中都没有,则会报错referenceError
- 在函数中访问全局变量可以使用window对象
- 函数作用域中var声明的变量也会提前;函数声明也会在所有代码执行之前也会被调用
- 在函数中不使用var声明的变量都会成为全局变量
- 形参就相当于在函数中声明了一个变量,调用函数时如果不写实参,就报undefined
- ==解析器调用函数每次都会向函数内部传递一个隐含参数this==,
- this指向的是一个对象,这个对象我们称之为==函数执行上下文对象==
- 根据函数的调用方式不同,this会指向不同的对象
- 以函数的形式调用时,this永远指向window
- 以方法的形式调用时,this就是调用方法的那个对象
1
2
3
4
5
6
7
8function fun(){
console.log(this.name);
}
var name = "全局的name属性";
//以方法的形式调用
window.fun();
//以全局的形式调用
fun();
- 工厂化方法创建对象
- 弊端是:所有的对象都是object的,是==通过new创建出来的对象==,不能区分不同的对象,因此提出构造函数的概念
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// 工厂化方法创建
function createPerson(name,age,gender){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayHello = function(){
alert(this.name);
}
return obj;
}
var obj1 = createPerson("猪八戒",13,"男");
var obj2 = createPerson("孙悟空",13,"男");
var obj3 = createPerson("汤森",13,"男");
var obj4 = createPerson("白龙马",13,"男");
obj1.sayHello();
obj2.sayHello();
obj3.sayHello();
obj4.sayHello();
- 弊端是:所有的对象都是object的,是==通过new创建出来的对象==,不能区分不同的对象,因此提出构造函数的概念
- 构造函数
- 创建一个构造函数专门用来创建指定的对象;构造函数是一个普通的函数,创建方式和普通的方式没有区别;不同的构造函数习惯首字母大写
- 构造函数和普通函数的区别:
- 普通函数是直接调用
- 构造函数是使用new关键字来调用
- 构造函数的执行流程:
- 立刻创建一个新的对象
- 将新建的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象
- 逐行执行函数中的代码
- 将新建的对象作为返回值返回
- 使用同一个构造函数创建的对象属于一类对象,也将一个构造函数称之为一个类
- 我们将通过构造函数创建的对象称之为==实例==
- 通过instanceof 可以判断对象实例所属情况,格式:==实例 instanceof 对象==
- this的三种情况:
- 当以函数形式调用,this是window
- 当以方法的形式调用,this是调用方法的对象
- 当以构造函数调用,this就是创建的函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27function Dog(name,age){
this.name = name;
this.age = age;
this.sayHello = function(){
alert(this.name);
}
}
function Person(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
this.sayHello = function(){
alert(this.name);
}
}
var per = new Person("猪八戒",12,"女");
console.log(per);
console.log(per.sayHello());
var dog = new Dog("小黄",23);
console.log(dog)
console.log(dog.sayHello())
// instanceof
console.log(per instanceof Object);
console.log(dog instanceof Dog);
console.log(per instanceof Person);
改进: 将sayHello()方法在全局作用域中定义,避免每次创建新的对象都会新建函数sayHello,占用内存
缺点:定义在全局变量中会污染全局变量的环境,因此提出了原型的概念 - ==原型解决方案==:
- 创建构造函数,可以将这些对象共有的属性和方法添加到构造函数的原型对象中,不用分别给每个独享添加,也不会影响到全局作用域,就可以使每个对象都可以访问到这些属性和方法
- ==原型==:
- 我们所创建的每个函数,解析器都会添加一个属性==prototype==,这个属性对应着一个对象,就是==原型对象==
- 函数调用
- 如果函数作为普通函数调用,原型没有任何作用;
- 作为构造函数调用,他所创建的每一个实例都会有一个隐含的属性指向该构造函数的原型对象,可以通过proto来访问
- 原型对象相当于一个类的公共区域,所有同一个类的实例都可以访问这个原型对象,可以将对象中共有的内容统一设置到原型对象中
- 当我们访问对象中属性和方法是,他现在自身中寻找,如果有则直接使用,否则会去原型对象中寻找
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21function MyClass(){
}
var c1 = new MyClass();
// 给实例中添加属性和方法
c1.a = "abc"
c1.fun = function(){
console.log("我是c1的方法");
}
var c2 = new MyClass();
console.log(MyClass.prototype==c1.__proto__);//返回结果为true,函数的属性prototype==实例的属性__proto__
// 给原型对象中添加属性/方法
MyClass.prototype.a = 123;
MyClass.prototype.fun = function(){
alert("hello");
}
// 访问原型对象中的内容
console.log(c1.fun());
console.log(c1.a);
console.log(c2.fun());
console.log(c2.a);
- 查看对象中的属性
- 使用in查看对象中的属性:使用in检查对象中是否含有某个属性,如果对对象中没有,原型对象中有,也会返回true;格式:”属性名” in 实例.
- 使用hasOwnProperty()来检查对象自身的属性,且只能检查自身的属性格式:实例.hasOwnProperty(“属性名”)
- hasOwnProperty()在原型的原型的对象中存在
- 原型的对象中也存在原型对象,当我们使用一个对象的属性或方法时,会现在自身中寻找,有则直接使用,没有则去原型对象中寻找,不存在在去原型的原型的对象中去寻找,直到找到object对象的原型,如果object中没有则返回undefined,==object对象中没有原型,原型为null==.
1
2
3
4
5in方法使用
"name" in c1
hasOwnProperty方法使用
per1.__proto__.hasOwnProperty("toString")
注意:查看函数方法也是只看方法名
- toString方法重写在原型对象中会对所有创建的实例都起作用
1
2
3
4// 定义在原型对象中显示
Person.prototype.toString = function(){
return "Person[name="+this.name+"age="+this.age+"gender:"+this.gender+"]";
} - ==垃圾回收(GC)==
- 不再使用的对象的内存将会==自动回收==,这种功能称作垃圾回收
- 所谓不再使用的对象,指的是没有任何一个属性(变量)引用的对象
- 垃圾回收目的:是开发者不必为对象的生命周期管理花费太多的时间object=null
- JS引擎中拥有自动垃圾回收机制,需要回收将obj=null
快捷键及查询网址
本文作者:
SparkParis
本文链接: https://sparkparis.github.io/2020/03/24/JavaScript-%E5%9F%BA%E7%A1%801/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!
本文链接: https://sparkparis.github.io/2020/03/24/JavaScript-%E5%9F%BA%E7%A1%801/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!