目录
JavaScript 入门基础 03
JavaScript构造函数
JavaScript
创建对象的方式有两种,一种是通过直接量的形式来创建对象,另外一种则是通过构造函数
的形式来创建对象。
简单的说,构造函数
就是在创建对象时通过new
关键字调用的函数,我们称之为构造函数
。
通常情况下构造函数的首字母应该大写。
我们说在js
当中,一切皆对象
。而所有的对象都存在有一个constructor
属性,通过这个属性
,我们可以查看到每一个对象
的构造函数
。
例如:
var str = 'hello,world!';// 创建一个字符串
// 查看str 的构造函数
console.log(str.constructor); // [Function: String]
在js
当中,我们也可以通过构造函数
来创建对象。
首先,我们来思考一个问题,我们为什么要使用构造函数来创建一个对象?
我们可以先来假设一种情况,在警局档案中有6个嫌疑人,现在我们需要来通过
代码存储这几个人的信息,我们如果采用直接量对象的形式来存储,写法大体如下:
var p1 = {name: "张三", age: 30, home: "山东"};
var p2 = {name: "李四", age: 50, home: "北京"};
var p3 = {name: "王五", age: 40, home: "上海"};
var p4 = {name: "赵六", age: 20, home: "江苏"};
var p5 = {name: "周七", age: 40, home: "安徽"};
var p6 = {name: "付八", age: 50, home: "云南"};
在上面的代码中,我们每一次都需要创建一个完整的对象,来存储不同的信息,很大程度上造成了代码的冗余。
而我们使用构造函数来创建代码,则可以把相同的内容进行封装,从而实现代码的简化和复用。
例如:
function Criminal(name,age,home){
this.name = name;
this.age = age;
this.home = home;
}
// 存储数据
var p1 = new Criminal('张三',30,'上海');
var p2 = new Criminal('李四',40,'北京');
var p3 = new Criminal('王五',20,'江苏');
// ...
在上面的代码中,我们创建了一个构造函数,并且通过new
关键字调用构造函数创建了对象。
相比之前的写法,虽然我们在创建构造函数的时候可能会麻烦一些,但是在创建对象的过程中则变得更加的简单。
从这一个角度来说,我们之所以使用构造函数,目的就是为了减少代码的重复书写,并且提高代码的复用性。
需要注意的是,我们之所以使用构造函数,是为了减少在使用对象直接量创建对象的时候那些重复编写的相似的代码。
通常情况下,构造函数和普通的函数其实看上去很相似,只有在通过
new
关键字调用的时候,才能确定一个函数到底是不是构造函数。
下面来说下构造函数的执行流程。
首先,我们先来创建一个用于测试的构造函数。
function SayHello(name) {
this.name = name ;
}
var s1 = new SayHello("zhangsan");
当我们通过new
关键字来创建一个对象的时候,相当于在内存中创建了一块新的内存空间,标记为SayHello
的实例。
在我们的代码中,this
关键字其实指向的就是存储在内存中的这个实例。
So,我们在使用new
关键字创建对象的实例,实际上每一次调用new
关键字都相当于在内存中开辟了一块新的内存空间。
而this
也会随着实例化对象的不同而改变指向。
所以,我们在代码中,给this添加属性其实也就相当于给未来的实例添加属性。
在构造函数
的最后,我们再来说下构造函数
的返回值。
在普通函数的最后,可以通过return
来设置函数的返回值,如果不设置返回值,那么默认返回值为undefined
。
但是在构造函数中,如果我们不设置返回值,就将默认返回this
。也就是指向内存中实例的那块内存空间,也就是相当于返回了那段存在
内存空间中的对象。
而如果我们在构造函数中手动的通过return
返回一个基本类型的值,那么返回值将不会受到影响,还是this
。
例如:
function SayHello(name) {
this.name = name ;
return "hello,world!";
}
var s1 = new SayHello("zhangsan");
console.log(s1); // SayHello { name: 'zhangsan' }
而如果return
返回的是一个引用对象类型
的数据,那么最终返回的则是对象。
例如:
function SayHello(name) {
this.name = name ;
return {
like:"I like you"
}
}
var s1 = new SayHello("zhangsan");
console.log(s1); // { like: 'I like you' }
上面只是简单的介绍了一下构造函数,构造函数的使用往往与
原型
和原型链
是分不开的。在后续的博文中会针对原型
和原型链
进行深入的说明,本章只是一个简单的介绍。
常用事件和事件处理函数
学习js
,不仅仅要学习其核心语法
,还要学习js
所在宿主环境当中的一些api
。
例如,当js
运行在浏览器
当中的时候,学习内容应该包括ECMAScript
核心语法,DOM
文档对象模型和BOM
浏览器对象模型。
在DOM
当中,存在有很多的事件,通过这些事件,我们能够很好地监听用户在浏览器网页当中的一些动作,并且根据这些动作来设置相关的事件处理函数。
例如用户在网页中发生了单击操作,双击操作,按下了键盘上的什么按键等等。
下面将来简单的说一些常用的事件,具体的事件讲解将在后续的博文中进行更新。
在本段博文中更主要的是来讲解事件处理函数的使用。
常用事件:
- 单击事件 onclick
- 双击事件 ondblclick
- 文档加载事件 onload
- 表单内容更改 onchange
上面列出了四个不同的事件,通过这些事件来说一下事件和事件处理函数。
首先,我们通常情况下使用事件都是具有一定原由的。
例如,我们使用了单击事件,目的是希望当用户发生了单击这个行为后,我们能够做出什么反应。
我们可以将事件分成三个部分,事件源,事件,以及事件发生后执行的动作。
对应着元素、事件以及事件处理函数。
例如:
按钮.单击= function () {事件发生后执行的动作}
例如我们在网页中有一个按钮,当用户点击按钮的时候我们让网页弹出弹窗,弹出信息为hello,world
。
具体代码可以如下:
// 找到按钮
var oBtn = document.getElementById('btn');
// 绑定事件
oBtn.onclick = function () { // 事件处理函数
// 当用户发生点击操作之后弹出弹窗
alert('hello,world');
};
在上面的代码中,我们通过给一个元素绑定单击事件,并且添加了事件处理函数。
一旦用户点击了按钮,那么就立刻会弹出弹窗。
当然,我们除了上面的写法以外,对于给一个元素绑定事件和事件处理函数的写法还可以换做另外一种形式:
<button id="btn" onclick="sayHello()">点击</button>
<script >
function sayHello(){
alert('hello,world');
}
</script>
在上面的代码中,我们把事件和事件处理函数都绑定到了元素的身上,这样做的好处是能够省略了获取元素的过程。
在我们执行事件处理函数的时候,在某些时刻可能需要进行参数的传递,那么该如何进行参数的传递呢?
可以采用下面的几种方式。下面同样是点击问好的案例,但是问好的对象是对指定的人进行问好。
第一种方式:
demo:
<button onclick="sayHello('张三')">点击问好</button>
<script >
function sayHello(name){
alert('hello,' + name );
}
</script>
第二种方式:
demo:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="text" id="name">
<button id="btn">点击问好</button>
</body>
<script>
// 获取input
var oInput = document.getElementById('name');
// 获取按钮
var oBtn = document.getElementById('btn');
// 点击按钮然后执行问好
oBtn.onclick = function () {
var userName = oInput.value;
sayHello(userName);
};
function sayHello(name) {
alert('hello,' + name);
}
</script>
</html>
上面的代码中,我们可以在input中输入用户名,当用户点击按钮的时候,我们会将通过单击事件的事件
处理函数来调用sayHello
方法,在这个方法中,获取用户输入的用户名,然后问好。
上面的代码基本上已经完成了我们的需求,但是我们仍然需要让我们的代码变得更加的完善。
例如,当我们点击按钮的时候,发现用户并没有输入用户名,我们该怎么办?
demo:
// 点击按钮然后执行问好
oBtn.onclick = function () {
var userName = oInput.value;
// 判断一下用户输入的内容是否为空
if (userName === "") {
alert("请输入用户名");
}else {
sayHello(userName);
}
};
在上面的代码中,当用户点击按钮调用了事件处理函数之后,我们进行了一个判断,判断用户输入的内容是否为空,如果为空,我们就可以继续提示用户,请输入用户名。
当然。上面的代码其实演示的仅仅是一种思路,代码仍然不是太严谨。
在我们的实际项目开发中,必须要让我们的代码尽可能的变得更加严谨,使我们的代码变得更加的强壮。
小练习
上面我们讲了阶乘的定义,那么我们现在来完成一个简单的小练习。
用户在输入框中输入任意的数字,我们来帮助用户完成这个数字的阶乘。并且将结果显示在网页当中。
demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>阶乘</title>
<style>
#value {
font-size: 40px;
color:green;
}
</style>
</head>
<body>
请输入需要计算阶乘的数字:
<input type="text" id="number">
<button id="btn">点击计算</button>
<br>
<div id="value"></div>
<script>
// 获取按钮
var oBtn = document.getElementById('btn');
// 创建阶乘计算函数
function factorial(number) {
var base_number =1;
for (var i=1;i<=Number(number);i++){
base_number = base_number * i;
}
return base_number;
}
// 获取div
var oDiv = document.getElementById('value');
// 获取input
var input = document.getElementById('number');
// 绑定单击事件
oBtn.onclick = function () {
// 获取用户输入的内容
var oInput = input.value;
// 将阶乘的结果赋值给oDiv
oDiv.innerHTML = factorial(oInput);
}
</script>
</body>
</html>
下面我们再来完成另外一个练习,当用户在输入框中输入用户名后,当用户输入完成后自动验证,我们来检测当前的用户名是否可用。
demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户名验证</title>
<style>
#check {
font-size: 40px;
}
</style>
</head>
<body>
<input type="text" id="username">
<div id="check"></div>
</body>
<script>
// 获取input 按钮 和 div
var oInput , oDiv;
oInput = document.getElementById('username');
oDiv = document.getElementById('check');
// 在变量中存储正确用户名
var user_right = "张三";
// 绑定onchange事件
oInput.onchange = function () {
// 获取用户输入的内容
var oInput_value = String(oInput.value);
if (oInput_value === user_right) {
// 如果用户名正确
oDiv.style.color = "green";
oDiv.innerHTML = "输入正确";
}else {
oDiv.style.color = "red";
oDiv.innerHTML = "输入错误";
}
}
</script>
</html>
数据类型之间的差异性
我们之前说过,js
的数据类型分为基础数据类型
和引用数据类型
。上面我们说过的string
、boolean
、number
等类型都属于基础数据类型
。
而我们说过的函数则属于引用数据类型
。
我们下面说的数组
类型同样属于引用数据类型
。
在学习数组
之前我们先来说下基础数据类型
和引用数据类型
的区别。
基础数据类型
又叫做原始数据类型
。通常情况下数据会存储在内存的栈
中。
例如,将hello,world
这个字符串存储在变量str
中。这个变量连同hello,world
都存在栈
中。
如果我们存在一个函数
或者数组
等引用数据类型
将其存在一个变量中,那么这个变量将会被存储在内存的栈
中。
而引用类型
的数据将会被存在内存的堆
中。
此时需要注意的是,变量和具体的引用类型
的数据是分开存储的,而存储在栈
中的变量里面存储的只是引用类型
的数据在堆
中存储的具体位置。
我们知道了基础数据类型
和引用类型
的数据在内存中不同的存储位置之后,我们还需要知道下面的这些内容。
首先,基础类型
的数据一旦创建之后不能够进行更改。
例如:
var a = "hello,world";
此时这个变量a
存储的数据为一个字符串,是一个基础数据类型
,我们对这个变量里面的内容,只具有读取的权限,但是并没有办法进行更改。
例如我们可以通过下标的形式进行查询:
console.log(a[0]);// h
但是我们并没有办法进行更改:
a[0] = "z";
上面的这种做法是完全行不通的。
而如果变量当中存储的数据是一个引用类型
的数据,例如下面我们要学习的数组:
var a = [10,20,30];
我们是可以进行更改的:
a[0] = "hello";
此时我们再来查看数组,是一个已经被更改的数组。
在很多的面试题当中,经常出现下面的题目:
var a = "hello,world";
var b = a;
b[0] = 'x';
console.log(b[0]); // h
console.log(a); // hello,world
console.log(b); // hello,world
当存储的数据变为引用类型的数据
:
var a = [10,20,30];
var b = a;
b[0] = 'hello,world';
console.log(b); // [ 'hello,world', 20, 30 ]
console.log(a); // [ 'hello,world', 20, 30 ]
在上面的代码中,通过b
对数据进行了更改,那么a也跟着发生了更改。
再来看下面的试题:
var a = "hello,world";
var b = a;
console.log(b); // hello,world
console.log(a); // hello,world
b = "admin";
console.log(a); // hello,world 变量a并没有发生变化
console.log(b); // admin 变量b相当于重新存储了数据,并且在内存中重新开辟了一块空间
在上面的案例中,我们将b重新的存储了新的数据,并不会对原本的变量a产生任何的影响。
数组
介绍
数组(array)
是按次序 排列的一组值。其中每一个值都有一个编号(编号默认从0开始).
当我们存储一系列值的时候,通常情况下都会使用数组,这样无论是从存储还是从查询获取等方面都很便捷。
创建
下面我们来说下如何创建一个数组,我们创建数组,通常情况下可以使用下面的两种方式:
第一种方式,是通过直接量的方式:
例如:
var test_arr = [10,20,30]; // 通过直接量的形式创建了一个数组
第二种方式,是通过构造函数的形式:
例如:
var test_arr = new Array();
console.log(test_arr); // []
// 也可以在使用构造函数创建的时候设置一个具体的值,例如
var test = new Array(10); // 相当于创建了一个空数组,并且长度为10
console.log(test); // [ <10 empty items> ] 打印出一个空的数组
console.log(test.length); // 10
var test_arr2 = new Array(10,20,30,40);
console.log(test_arr2); // [ 10, 20, 30, 40 ]
在上面的两个案例中,我们通过直接量
和构造函数
的形式创建了数组,两种方式都能够创建出我们想要使用的
数组。但是无论是从创建速度
还是运行效率
来讲,直接量
的形式都优于构造函数
的形式。
所以当我们需要创建一个数组的时候,推荐使用直接量
的形式来创建数组。
下面我们来具体的说下,当我们使用构造函数创建数据的时候,与直接量创建数据的时候二者之间的区别。
当我们使用构造函数
的形式来创建数组的时候,通常情况下,需要经历以下的过程:
- 首先创建函数
- 查询作用域链
- 创建作用域链
- 将数据写入
而我们使用直接量
的形式来创建数据,相当于直接将数据写入内存中,速度是最快的,相当于直接作用在作用域链条中。
而作用域链条
在es5
中存在两条。一条是var
,也就是变量的作用域,另外一条是函数声明
。在代码执行的过程中优先查找非函数链条
。顺序是从下到上,而函数链条顺序是从上到下。
通常,我们在执行js代码的阶段,通过直接量直接向内存中存储数据的速度是最快的,其次是通过变量声明,最后是通过函数调用获得的变量。
下面是关于直接量的补充扩展内容:
1976.6 ES1中,直接量有四种:null、boolean、numeric、string
1998.8 ES2中,与ES1相同
1999.12 ES3中,直接量加入了Regular
2011.6 ES5.1 与上面相同
而在ES3和ES5
当中,将数组和对象
纳于表达式
一章里,称之为初始器(Initialiser)
。
在很多经典的js书籍里,将对象和数组都称之为对象直接量
和数组直接量
,为什么会有这种说法呢?
原因是,这些书籍的出版时间略早于上面规则的更改。
数组的常规使用
需要注意的是,当我们创建了一个数组,并且使用typeof
查看其类型,会发现其类型为object
。
var arr = [10,20,30,40];
console.log(typeof arr); // object
明明是数组,为什么会查看其类型为object
呢?原因是因为在js当中,数组也是一种特殊类型的object。
我们如果想要来判断数组类型,可以通过instanceof
来进行判断。
例如:
var arr = [];
console.log(arr instanceof Array); // true
在js
当中,数组被定性为一种特殊的对象。
下面我们来说一下在创建一个数组
之后,数组
的一些常规操作:
创建数组:
demo:
// 数组的常规操作
// 创建一个空数组
var arr1 = [];
// 通过索引值的形式向数组中添加内容
arr1[0] = '张三丰';
arr1[1] = '张无忌';
arr1[2] = '张翠山';
// 打印查看数组
console.log(arr1); // [ '张三丰', '张无忌', '张翠山' ]
// 也可以在创建数组的初期向数组中添加内容
var arr2 = ['张三丰','张无忌','张翠山'];
console.log(arr2); // [ '张三丰', '张无忌', '张翠山' ]
// 通过构造函数的形式来创建一个数组
var arr3 = new Array(); // 创建一个空数组
// 向数组中添加内容
arr3[0] = '张三';
arr3[1] = '李四';
arr3[2] = '王五';
console.log(arr3); // [ '张三', '李四', '王五' ]
// 通过构造函数的形式创建一个数组
var arr4 = new Array('张三','李四','王五');
console.log(arr4); // [ '张三', '李四', '王五' ]
下面是数组的查找:
var arr1 = ['张三','李四','王五'];
// 查找数组当中指定位置的元素
console.log(arr1);// 打印全部的数组元素
console.log(arr1[0]); // 张三 通过索引下标来查找元素
console.log(arr1[2]); // 王五
当我们进行数组元素查找的时候,一旦索引值超过最大范围,则为
undefined
。
// 超过数组索引值最大值
console.log(arr1[100]); // undefined
当我们想要修改数组中的具体元素的时候,可以直接通过索引值找到这个元素并且进行重新赋值。
var arr1 = ['张三','李四','王五'];
// 通过索引值下标对数组元素中的具体元素进行修改
arr1[0] = '赵三';
arr1[2] = '欧阳';
console.log(arr1); // [ '赵三', '李四', '欧阳' ]
下面的操作是数组的删除操作,在下面的案例中主要通过delete
运算符进行删除。
// 删除数组中的元素
var arr1 = ['张三','李四','王五'];
delete arr1[0];
console.log(arr1); // [ <1 empty item>, '李四', '王五' ] 当我们通过delete 删除了元素之后,元素虽然被删除,但是位置依然存在,会被undefined占据
// 访问一下被删除的空位
console.log(arr1[0]); // undefined
在上面的代码中,我们通过delete
运算符删除了数组元素,但是需要注意的是,虽然我们删除了元素,但是被删除的元素所在的位置依然被保留,只不过被undefined
取代。
数组的length属性
在Array
对象当中,存在一个length
属性,能够用来查看数组的长度。
例如:
var arr = [10,20,30,40];
console.log(arr.length);// 4
通常情况下,我们可以通过将length
属性值设置为0,来让数组清空。
例如:
var arr = [10,20,30,40];
arr.length = 0;
console.log(arr); // [] 数组被清空
有一点我们是需要注意的,因为数组也是一种特殊的对象,所以我们通常情况下,数组索引值的设定,除了采用默认的索引值外,还可以采用自定义
索引值的索引。
但是一旦我们采用了自定义索引值的索引,那么这个数组里面的length
属性将会为失效。
var arr = [];
arr['hello'] = 'hello,world';
console.log(arr); // [ hello: 'hello,world' ]
arr['world'] = 'this is my new world';
console.log(arr); // [ hello: 'hello,world', world: 'this is my new world' ]
console.log(arr.length); // 0
数组当中常见的操作方法
在数组中,经常使用的操作方法有以下的几个
- push
- pop
- unshift
- shift
首先来说下push()
方法。通过这个方法,我们能够将一个或者多个元素添加到数组的末尾,并且返回数组的新长度。
// 创建一个数组
var arr1 = ['张三','李四'];
// 通过Push方法向数组中添加元素
arr1.push("王五");
// 检查数组内容
console.log(arr1); // [ '张三', '李四', '王五' ]
// 尝试添加多个内容
arr1.push("赵六","刘七");
// 打印数组元素
console.log(arr1); // [ '张三', '李四', '王五', '赵六', '刘七' ]
// 创建一个新的数组
var arr2 = [1,2,3,4];
// 尝试将arr2添加到arr1
arr1.push(arr2);
// 打印arr1;
console.log(arr1); // [ '张三', '李四', '王五', '赵六', '刘七', [ 1, 2, 3, 4 ] ]
// 向arr1中再次添加数据并且查看push方法的返回值
console.log(arr1.push('hello,world')); // 7
pop()
方法能够从数组中删除最后一个元素,并且返回该元素的值。此方法更改数组的长度。
var plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato'];
console.log(plants.pop());
// expected output: "tomato"
console.log(plants);
// expected output: Array ["broccoli", "cauliflower", "cabbage", "kale"]
plants.pop();
console.log(plants);
// expected output: Array ["broccoli", "cauliflower", "cabbage"]
上面我们演示了pop
方法删除数组的最后一个元素,但是在使用pop
方法的时候,我们需要注意,该方法通过length
属性来确定最后一个元素的位置,
如果不包含length属性或者length属性不能够被转换成一个数值,那么就会将length属性设置为0,并且返回undefined。
同时,你在一个空数组上调用pop方法,也会返回undefined。
arr.pop();
console.log(arr);// 并没有删除成功
console.log(arr.pop()); // undefined
unshift()
方法能够将一个或者多个元素添加到数组的开头,并且返回数组的新长度。
var array1 = [1, 2, 3];
console.log(array1.unshift(4, 5));
// expected output: 5
console.log(array1);
// expected output: Array [4, 5, 1, 2, 3]
shift()
方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
var array1 = [1, 2, 3];
var firstElement = array1.shift();
console.log(array1);
// expected output: Array [2, 3]
console.log(firstElement);
// expected output: 1
shift 方法移除索引为 0 的元素(即第一个元素),并返回被移除的元素,其他元素的索引值随之减 1。如果 length 属性的值为 0 (长度为 0),则返回 undefined。
shift 方法并不局限于数组:这个方法能够通过 call 或 apply 方法作用于类似数组的对象上。但是对于没有 length 属性(从0开始的一系列连续的数字属性的最后一个)的对象,调用该方法可能没有任何意义。
数组的遍历
遍历
指的是将对象当中的内容全部输出出来,而数组
的遍历可以通过for
循环和专门针对对象的for..in
循环来实现。
var arr = ['hello','world','how are you','nice to meet you'];
// 循环遍历数组
for(var i=0;i<arr.length;i++){
console.log(arr[i]);
}
// 第二种遍历数组的方式
for (var j in arr) {
console.log(arr[j]); // 同样可以实现遍历数组的目的
}
数组的分类
在js
当中,数组可以分为稀疏数组
、多维数组
、自定义索引数组
等等。
下面来说一下这几种类型的数组以及在使用的过程中需要注意的内容。
需要注意的是,数组是一种特殊类型的对象,所以数组的里面可以存储任意类型的数据。
稀疏数组
当数组的索引值处于不连续状态的时候,被称为稀疏数组
。
var arr = [];
arr[0] = 'hello';
arr[2] = 'world';
arr[10] = 'test';
上面我们在创建的过程中指定了索引值,但是索引值并不连续,所以此时这个数组我们可以称之为稀疏数组
。
一旦我们主动的或者被动的创建了一个稀疏数组,那么我们在遍历数组的过程中将会非常容易出现问题。
var arr = [];
arr[0] = "hello";
arr[3] = "world";
arr[6] = "test";
console.log(arr); // 我们创建了一个稀疏数组
// 循环输出数组
for(var i=0;i<arr.length;i++){
console.log(arr[i]); // 会将空位输出undefined
}
在上面的代码中,我们创建的稀疏数组,一旦索引值不连续,那么就会形成空位。空位在js当中会被undefined代替。
多维数组
上面我们说到,js当中的数组里面可以存储任何类型的数据,当然也包括数组,即在一个数组里面存储另外的数组,这样的数组我们称之为多维数组。
例如:
var arr = [[1,2,3],[4,5,6]];
console.log(arr); // [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
我们如果想要操作多维数组,依然可以采取索引值的形式,整体的操作形式与一维数组相同。
自定义索引数组
上面我们在创建数组的过程中,曾创建过自定义索引的数组。
例如:
// 自定义索引数组
var arr = [];
arr['name'] = '张三';
arr['age'] = 30;
arr['like'] = '吃喝嫖赌';
document.write(arr); // 网页当中并没有效果
document.write(arr['name']); // 张三
document.write(arr['age']); // 30
document.write(arr['like']); // 吃喝嫖赌
console.log(arr);// [name: "张三", age: 30, like: "吃喝嫖赌"]
需要注意的是,数组因为是一种特殊类型的对象,所以数组的索引值无论是默认的数值还是我们设定的自定义索引,其实类型都是字符串类型。
即使索引值在创建之初看上去并不像是一个字符串,但是在代码的运行过程中也会被转换为字符串类型。
小练习
- 山上有一口缸可以装50升水,现在有15升水。老和尚叫小和尚下山挑水,每次可以挑5升。问:小和尚要挑几次水才可以把水缸挑满?通过编程解决这个问题。
var water = 50;
var now_water = water - 15;
var step = now_water / 5 ;
console.log(step); // 7
数组的排序
- 冒泡排序
所谓的冒泡排序,其实指的是对数组中的数据进行排序,按照从小到大的顺序来进行排列.
生活原理:假设小明是最矮的;然后通过比较,发现二狗要比小明矮,就和小明换位置,两两比较,通过第一次比较可以找出二狗是最矮的人,
然后假设队伍的第二个人是最矮的,让他和剩下的人比较身高,依次找出其他人的位置。
js思路:假想数组中的任意一个值是最小;然后通过比较两两比较,找出索引值,换位,然后赋值。
// 数组的冒泡排序
var arr = [10,3,4,2,32,43,100,99];
maoPao(arr);
// 希望对上面的数组进行冒泡排序的处理
// 将两个值进行对比
function maoPao(arr) {
var flag = 1; // 用来标记某一次排序是否发生交换
for(var i =0;i<arr.length-1;i++) {
flag = 0; // 设置为0表示没有发生交换
for (var j =0;j < arr.length-i-1;j++){ // arr.length - i - 1相当于 arr.length - (i + 1 ) 因为一次循环比较的是一个值,所以这一步求出的剩余的没有比较的次数
if (arr[j] > arr[j+1]) {
// 进行交换
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = 1; // 设置为1 表示本次循环发生了交换
}
}
console.log(arr); // 每次都输出一下数组
if(flag === 0) break; // 如果没有发生改变,则停止循环
}
}
- 选择排序
生活原理:假设小明是最矮的;然后通过比较,发现二狗要比小明矮,
就和小明换位置,两两比较,通过第一次比较可以找出二狗是最矮的人,
然后假设队伍的第二个人是最矮的,让他和剩下的人比较身高,依次找出其他人的位置。
js思路:假想数组中的任意一个值是最小;然后通过比较两两比较,找出索引值,换位,然后赋值。
// 数组的冒泡排序
var arr = [10,3,4,2,32,43,100,99];
xuanZe(arr);
function xuanZe(arr) {
for(var i=0;i<arr.length-1;i++){
// 假设此时最小值
var min = arr[i];
// 假设此时最小值所在的索引
var index = i;
for (var j = i + 1;j < arr.length;j++){
if (min > arr[j]) {
index = j;
min = arr[index];
}
}
var temp = arr[i];
arr[i] = arr[index];
arr[index] = temp;
}
console.log(arr);
}
小练习
随机点名:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>随机点名</title>
<style>
#name {
width: 300px;
height: 300px;
border: 2px solid red;
text-align: center;
line-height: 300px;
font-weight: bold;
font-size: 80px;
}
</style>
</head>
<body>
<div id="name">
hi!
</div>
<button onclick="start()">开始</button>
<button onclick="end()">结束</button>
</body>
<script>
// 声明变量
var time, // 计时器
div,
name; // 选中的用户名
div = document.getElementById('name');
// 创建一个数组用来存储数据
var name_list = ["张三", "李四", "王五", "赵六","张1","张2","张3",'张四'];
function start(){
// 生成一个随机数
var num = Math.floor(Math.random() * name_list.length);
// 根据随机索引值来确定选中的姓名
name = name_list[num];
// 更改网页里div的值
div.innerHTML = name;
time = setTimeout("start()",100);
}
function end() {
clearTimeout(time);
}
</script>
</html>