js基础

js 笔记

javaScript的历史

java和javaScript的关系

JavaScript和Java是两种不一样的语言,但是它们之间存在联系。

JavaScript的基本语法和对象体系,是模仿Java而设计的。但是,JavaScript没有采用Java的静态类型,java需要编译器编译运行。

javaScript与ECMAScript的关系

ECMAScript 是一套语言标准,包含:

  1. javascript
  2. jscript
  3. actionscript

javaScript与ECMAScript的区别

ECMA是javascript的标准,javascript是ECMA的实现。

js代码引入

  1. 使用内嵌方式引入js代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>

  <!-- 内联引用 -->
  <script>
  var name='张三';
  </script>
</head>
  1. 外联方式引入代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>

  <!-- 外联引用 -->
  <script src="js/main.js"></script>
</head>
<body>

当script标签和link标签同时出现在head区域,那建议script标签写在link标签的后面,这样以保证样式优先加载,不会因为js代码执行阻塞页面渲染。

如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <link rel="stylesheet" href="css/style.css">
  <script src="js/main.js"></script>
</head>
<body>

根据YUI前端性能小组建议script标签放置在</body>的前面最佳。

如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <link rel="stylesheet" href="css/style.css">
</head>
<body>

  <!-- 外联的方式引用 -->
  <script src="js/main.js"></script>

</body>
</html>

js注释

  1. 单行注释 //
<script>
//注释1
//注释2
//注释3
var name='张三';
</script>
  1. 多行注释
<script>
/*
注释1
注释2
注释3
*/
var name='张三';
</script>

优先考虑单行注释,因为多行注释有可能会造成语法错误。

语句和表达式

语句和表达式的区别

语句指一个为了得到返回值的计算式。语句和表达式的区别在于,前者主要为了进行某种操作,一般情况下不需要返回值;后者则是为了得到返回值,一定会返回一个值。

  1. js代码通常是以英文状态分号结束;
  2. js代码会自动过滤字符之间空格、换行、缩进
  3. js代码严格区分大小写

变量

变量是对值的引用,变量就是为“值”起名,然后引用这个名字。

var sum = 1+3*10;
alert(sum);//警告框输出
document.write(sum);//文档输出
console.log(sum);//控制台输出,调试代码

变量命名规则

声明变量使用关键字var,使用此关键字声明的变量没有作用域

如果想要有作用域,可以使用es6种的letconst这两个关键字。

声明一个变量,一次都没有给它赋值,那么它的值是未定义undefined

  1. 单个逐行声明
var a = 1;
var b = '您好';
var c = 20;
  1. 多个一次声明
var a = 1,
    b = '您好',
    c = 20;

  1. var变量会自动提升
console.log(a);//undefined
var a = 10;

// 以上代码变量会自动提升,相当于下面的代码
var a;
console.log(a);
a = 10;

仔细理解一下代码的区别

//会提升
console.log(a);
var a = 10;

//会报错,因为没有var关键字
console.log(a);
a = 10;

  1. 变量命名要求

语法

var 变量名 = 值;

变量名,以字母、下划线、或中文开头,后面允许使用字母、数字、中文。特殊符号仅限`_`,变量字符之间不要存在空格。

变量命名不能使用(保留字)关键字 if、else、break、with等等

变量命名严格区分大小写

// 错误的命名
var 1a = 10;
var a 1= 20;
var %a = 30;
var a,3 = 20;
var var = 10;
var if = 20;

//正确的命名
var a1 = 20;
var A1 = 30;
var _abc = 10;
var $ab = 20;
var 姓名 = '张三';

  1. 变量命名风格

Camel Case 小驼峰式命名法

var fullName = '张亮';

Pascal Case 大驼峰式命名法

var FullName = '张亮';

常量命名,通常全部大写

//比如圆周率就是典型的常量
var PI = 3.14;

条件语句

if条件语句

  1. if 单条件语句
var age = 30;
if ( age >= 18) { 
  console.log( '您已经成年!' );
}

// 条件语句也可以使用下面的风格
var age = 30;
if ( age >= 18)
{ 
  console.log( '您已经成年!' );
}

//简写,仅限条件语句中只有一条语句时成立。
var age = 30;
if ( age >= 18) console.log( '您已经成年!' );


  1. if else 双条件语句
var age = 30;
if ( age >= 18 ) { 
  console.log( '您已经成年!' );
}else{
  console.log( '未成年!' );
}

//简写,仅限条件语句中只有一条语句时成立,不推荐这样写。
var age = 12;
if ( age >= 18)
  console.log( '您已经成年!' );
else
  console.log( '未成年!' );

  1. if else if else 多条件语句

&& 并且
||或者

// < 60 不及格
// >= 60 && <70 及格
// >= 70 && <80 良好
// >= 80 && <90 优秀
// >= 90 极好

var score = prompt('请输入你的分数:');

if ( score < 60 ){
  console.log('不及格');
}else if( score >= 60 && score < 70 ){
  console.log('及格');
}else if( score >= 70 && score < 80 ){
  console.log('良好');
}else if( score >= 80 && score < 90 ){
  console.log('优秀');
}else{
  console.log('极好');
}

switch条件语句

语法

switch( 表达式 ){
  case 值1:
    //跳出条件语句
    break;
  case 值2:
    //跳出条件语句
    break;
  case 值3:
    //跳出条件语句
    break;
  default:
    //输出默认结果
}

注意:switch执行值是严格匹配的,也就是说 5 不等于 '5'

示例

var day = new Date().getDay();

switch( day ){
  case 0:
    console.log('星期日');
    break;
  case 1:
    console.log('星期一');
    break;
  case 2:
    console.log('星期二');
    break;
  case 3:
    console.log('星期三');
    break;
  case 4:
    console.log('星期四');
    break;
  case 5:
    console.log('星期五');
    break;
  case 6:
    console.log('星期六');
    break;
  default:
    console.log('无效的值');
}

循环语句

  1. for循环语句

语法:

for ( 初始值;条件表达式;变量 ) {
  // 循环体内语句
}

示例

for ( var i = 0;i<100;i++ ) {
  console.log(i);
}

循环也可以把括号中的语句提出到外面,或者置入循环体中

//初始语句外置
var i = 0;
for ( ;i<100;i++ ) {
  console.log(i);
}

//变量语句内置
for ( var i = 0;i<100; ) {
  console.log(i);
  i++;
}

for循环支持嵌套循环

for{
  for(){
  }
}

示例

//1. 循环输出 0-99
for ( var i = 0;i<100; i++  ) {
  console.log(i);
}

//2. 循环输出 99-0
for( var i=99; i >= 0; i-- ){
  console.log( i ); 
}

//3. 循环输出 0-100的偶数  10 % 3 == 1 , 10 % 5 == 0 % 表示 取余数
for ( var i = 0;i<100; i++  ) {
  if(  i % 2 == 0 ){
    console.log(i);
  }
}


//4. 循环输出 0- 100 的总和
var sum = 0;
for ( var i = 0;i<=100; i++  ) {
  sum = sum + i;//累积
}
console.log( sum );

//5. 九九乘法表
for( var i=1; i<=9; i++ ){

  for( var j = 1; j <= i; j++ ){
    document.write( j, '*', i, '=', i*j,'&nbsp;&nbsp;&nbsp;' );
  }
  document.write('<br>');

}

breakcontinue关键字

  1. while循环语句

语法

while( 条件表达式 ){
  //循环体语句
  //变量
}

示例

var i=0;
while(i<100){
  console.log(i);
  i++;
}

var i=99;
while(i>=0){
  console.log(i);
  i--;
}

breakcontinue可以用循环语句中,用来跳出循环

var i=0;
while(i<100){
  i++;//放前面,不然会死循环
  if(i==50) continue;
  console.log(i);
}

forwhile语句可以混合使用

  1. do while循环语句

do while 无论条件真或假,至少执行一遍。

语法

do {
  // 循环体语句
} while ( 条件表达式 );

示例

var i=0;
do {
  console.log(i);//0
} while ( i > 10 );

js数据类型

数值 Number

js只有一种数值类型,浮点类型。

var age = 20; //正整型
var price = 34.2; //浮点型
var price = -30; //有符号整型

科学计数法

123e3 // 123000
123e-3 // 0.123
-3.1E+12
.1e-23

正零和负零

-0 === +0 // true
0 === -0 // true
0 === +0 // true

NaN 表示非数字,它的数据类型是数值类型

注意:NaN不等自己

NaN == NaN //false 

字符串 String

通常用双引号或单引号包裹的字符,我们称为字符串

单引号里面可以使用双引号,双引号里面可以使用单引号

var name = "张三";
var name = '张三';

//双引号中嵌套使用单引号
var str = "I'm a boy";

//单引号中嵌套使用双引号
var str = '我喜欢吃"苹果"';

//使用转义符,可以安全的输出。
var str = 'I\'m a boy';
var str = "我喜欢吃\"苹果\"";


推荐:优先考虑使用单引号

字符串和变量拼接

字符串和变量用加号+连接:

  • 变量在开头,只需要右加号
var name = '张三';
var str = name + '是我!';

  • 变量在中间,需要左右两个加号
var name = '张三';
var str =  '我是' + name + '本人。';

  • 变量在末尾,只需要左加号
var name = '张三';
var str =  '我是' + name;

示例

var name = '张三';
var age = 19;
var xueli = '本科';
console.log('我叫' + name +',今年'+age+'岁。\n 我的学历是'+xueli);

字符串代码不能强制折行,会报错,解决方案如下:

  • 字符串拼接换行(差,书写麻烦)
  • 末尾加转义符换行(良好)
  • es6字符串模板(好用,但要考虑兼容性)
<script>
var name = '张三';
var age = 20;
var xueli = '本科';
var str = `<table border="1">
  <tr>
    <th>${name}</th>
    <th>${age}</th>
    <th>${xueli}</th>
  </tr>
</table>`;
document.write( str );
</script>

布尔类型 Boolean

布尔类型只有两个值,true 真和 false

布尔相关运算符

  1. &&:并且,和,与的意思
  2. ||: 或者的意思
  3. !:取反,否定,排除的意思
  4. ===:严格等于
  5. ==:等于
  6. !==:严格不等于
  7. !=:不等于
  8. >:大于
  9. >=:大于或等于
  10. <: 小于
  11. <=:小于或等于

===== 的区别

==它会转换两端的数据类型,以保持相等。
===它不会转换两端的数据类型,严格等于。

console.log( 1 == '1' );//true 隐式转换
console.log( 1 === '1' );//false

js有那些值会自动转换为假?

  • false 假值
  • 0 数值零
  • '' 空字符串
  • null
  • undefined 未定义
  • NaN 非数字

注意:[]和{} 空数组和空对象都是真值

字符串中注意,只要有值,都是为真值,比如:'0'' ''false'都是真值

未定义 undefined

表示一个变量声明了,但是从来没有赋值

空 null

表示变量为空,null 它本质上是一个对象。

undefinednull的区别:

  • undefined 表示声明变量,未赋值
  • null 表示变量值为空
  • undefined 是基本数据类型
  • null 通过typeof检测它是对象类型

函数 function

函数本身也是一个值,函数允许将多行代码封装起来,然后通过函数名调用,方便代码组织和管理。

function add( c, d){
  console.log(c+d );
}
add( 1, 3 );

数组 array

数组是一种集合,存入各种数据类型,可以很方便存取操作,数组是有序的。

var arr = ['苹果','桔子'];
console.log( arr[1] );

对象 object

对象是变量的集合,对象是无序的。

var person = {
  age: 20,
  name: '张三',
  chengnian: true,
  habby: ['篮球','美食']

}
console.log( person.habby[1] , person['habby'][1] );

符号 symbol

es6 新增的数据类型,表示唯一值

数据类型总结

js基本类型有那些?

  • 数值
  • 字符串
  • 布尔
  • 对象
  • undefined

js 有那些数据类型?

  1. 数值
  2. 字符串
  3. 布尔
  4. 对象
  5. 未定义 undefined
  6. 符号 symbol
  7. 空 null

typeof 检测数据类型

请问typeof能检测的数据类型有那些?

  1. number
  2. string
  3. boolean
  4. object
  5. undefined
  6. function
  7. symbol
var a = 10;
var b = '字符串';
var c = true;
var d = [];
var e = {};
var f = Symbol();
var h = null;
var i = undefined;
var g = function(){};
var j = NaN;
var k = '';

console.log( typeof a); // number
console.log( typeof b); // string
console.log( typeof c); // boolean
console.log( typeof d); // object
console.log( typeof e); // object
console.log( typeof f); // symbol
console.log( typeof h); // object
console.log( typeof i); // undefined
console.log( typeof g); // function
console.log( typeof j); // number
console.log( typeof k); // string

因为typeof检查对象和数组返回都是object,如何区分?

var o = {};//对象
var a = [];//数组

//方法1
o instanceof Array // false
a instanceof Array // true

//方法2
Array.isArray( o ) // false
Array.isArray( a ) // true

//方法3


数值类型

与数值相关的全局方法:

  1. parseInt() 将字符串转换数值整型
var a = '100px';
var b = '100 200';
var c = '¥100';
var d = '';
var e = '2e3';

console.log( parseInt(a) );// 100
console.log( parseInt(b) );// 100
console.log( parseInt(c) );// NaN
console.log( parseInt(d) );// NaN
console.log( parseInt(e) );// 2

  1. parseFloat() 将字符串转换数值浮点型
  2. number() 将字符串转换为数值
var a = '100px';
var b = '100 200';
var c = '¥100';
var d = '';
var e = '2e3';
var f = '200.67';

console.log( Number(a) ); // NaN
console.log( Number(b) ); // NaN
console.log( Number(c) ); // NaN
console.log( Number(d) ); // 0
console.log( Number(e) ); // 2000
console.log( Number(f) ); // 200.67

  1. isNaN:判断是否是非数字,返回真与假

isNaN 它会隐性的将字符串转为数字,然后判断它是否是非数字

var a = '10';
var b = '十';
console.log( isNaN(a) );//false
console.log( isNaN(b) );//true

数值实例的方法

toFixed 将数值保留指定的小数位数,支持四舍五入。

var price = 100.679;
console.log( (200).toFixed(2) );  //正整型要加括号,不然会报错
console.log( 120.679.toFixed(2) ); //浮点不需要
console.log( '120.679'.toFixed(2) ); //报错,因为toFixed是数值的方法,不是字符串的方法
console.log( price.toFixed(2) );//100.68

给数值实例扩展方法

//扩展方法1
Number.prototype.CNY = function( len ){
  return '¥'+this.toFixed( len );
}
var num = 100;
console.log( num.CNY( 2 ) );


//扩展方法2
Number.prototype.add = function( n ){
  return this + n;
}
var a = 1;
console.log( a.add(2).add(5) );

隐式数据类型转换有那些?

console.log( 1 == '1' );  //true
console.log( 1 - '1' );  //0
console.log( 2 - true ); //1
console.log( 2 - [] ); //2
console.log( 2 - '' ); //2

字符串类型

字符串就是零个或多个排在一起的字符,放在单引号或双引号之中。

var a = 张三; //错误,必须加引号
var a = '张三';

转义符

常用转义符

  • \n:换行符
  • \r:回车键
  • \':单引号
  • \":双引号
  • \\:反斜杠
  • \t:制表符

字符串与数组

  1. 数组和字符串 都有长度,也有下标(索引值)
  2. 数组的长度可读写,而字符串只可读,不可写。
  3. 字符串不可以通过索引值方式改变成员的值。
  4. 字符串是类数组对象
//数组
var arr = ['你','今','天','心','情'];

//类数组对象
var obj = {
  0: '你',
  1: '今',
  2: '天',
  3: '心',
  4: '情',
  length: 5
}

//类数组对象
var str = '你今天心情';

console.log( arr[1], obj[1] );

arr.length = 10;
obj.length = 10;

console.log( arr.length, obj.length );


var arr = ['你','今','天','心','情'];
var str = '你今天心情';
arr[1] = '昨';//可以写入
str[1] = '昨';//字符串不可以写入

console.log( arr , str );


Base64 转码

var str = 'Hello World!';

//将ASCII编码转换为base64编码
console.log( btoa( str ) );//SGVsbG8gV29ybGQh

var base = 'SGVsbG8gV29ybGQh';

//将base64编码转换为ASCII编码
console.log( atob( base ) );//Hello World!

中文不能直接转为base64编码

//将中文转换为ASCII编码
var str = encodeURIComponent('你好,世界');

//将ASCII编码转换为base64编码
console.log( btoa( str ) );//JUU0JUJEJUEwJUU1JUE1JUJEJUVGJUJDJThDJUU0JUI4JTk2JUU3JTk1JThD


//将base64编码转换为ASCII编码
var base = atob('JUU0JUJEJUEwJUU1JUE1JUJEJUVGJUJDJThDJUU0JUI4JTk2JUU3JTk1JThD');

//将ASCII编码转换为中文
console.log( decodeURIComponent( base ) );//你好,世界

我们可以封装为两个函数,这样转码会方便多了

function b64Encode(str) {
  return btoa(encodeURIComponent(str));
}

function b64Decode(str) {
  return decodeURIComponent(atob(str));
}

b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"

7月16日

String对象

将其他数据流类型转换为字符串

String(true) // "true" 将布尔转换为字符串
String(12345) // "12345" 将数字转换为字符串
String([]) //'' 将数组转化为字符串,但功能很弱

String.fromCharCode

将一个或者多个unicode码点转换为好识别的字符串

String.fromCharCode() // ""
String.fromCharCode(97) // "a"
String.fromCharCode(104, 101, 108, 108, 111)
// "hello"

字符串的长度

'abc'.length 

字符串长度只读,不可写。

String实例的方法

charAt 返回指定索引值的字符

var str='今天的天气怎么样?';
console.log( str[0], str.charAt(0) );//今 今 

charCodeAt 返回指定索引值的unicode码点

'abc'.charCodeAt(1) // b 的nicode码点是 98

concat 拼接字符串,类似于加号。

连接过后产生新字符串

var a = '你好';
var b = '张三';

console.log( a + b );
console.log( a.concat(b) );
console.log( a.concat(b,'李四','王五') );

slice 从指定的位置,分割字符串。

位置计算规则

  • 位置从0开始计算,大于等于起始位置,小于结束位置。
  • 如果位置的值是负数,则倒着数,比如-1为倒数第1个,分割出一个新字符串。
  • 省略结束位置,表示截取到末尾

语法

字符串.slice(起始位置, 结束位置);

slice小示例

var str = '你今天的心情好吗?';

//1. 始终截取第1个字符串
console.log( str.slice(0,1) );

//2. 始终截取最后1个字符串
console.log( str.slice(-1) );

//3. 始终截取倒数3个字符
console.log( str.slice(-3) );

//4. 始终截取首尾单个字符串。
console.log( str.slice(0,1)+str.slice(-1) );

//5. 将字符串分割指定的段数。 你今、天的、心情、好吗、?

var total = str.length; //总字符数
var perPart = 5; //每段分2个字符
var totalPart = Math.ceil(total/perPart);  //上舍入 总段数

for(var p=0;p<totalPart;p++){
  var start = p * perPart;//4
  var end = start + perPart;//6
  console.log( str.slice( start, end ) );//2 4
}


substring 分割数组

slice方法很相像。它的第一个参数表示子字符串的开始位置,第二个位置表示结束位置。
如果省略第二个参数,则表示子字符串一直到原字符串的结束。

注意:substring的参数不支持负数

substr 截取字符串

语法

起始位置支持负数,如果是负数,那么倒着数,比如-1就是倒数第一个。

字符串.substr(起始位置,截取字符的长度);

var str = '你今天的心情好吗?';
console.log(  str.slice(4,6) );//起始位置 结束位置
console.log(  str.substr(4,2) );//起始位置 截取长度

indexOf 查找字符第一次出现的位置(索引值)

如果指定的字符不存在,则返回-1

语法

字符串.indexOf('要查找的字符','起始位置,默认是0')

示例

var str = 'xianweb@qq@.com';
var index = str.indexOf('@')+1;//8
console.log(str.indexOf('@', index));//查找第二个@

lastIndexOf 查找字符最后一次出现的位置(索引值)

如果指定的字符不存在,则返回-1

var str = 'xianweb@qq@.com';
console.log(str.lastIndexOf('@') );//查找第二个@

示例

var url = 'http://www.baidu.com/product/index.html';

//1. 截取网址文件名部分 index.html
console.log( url.slice(url.lastIndexOf('/')+1) );

//2. 截取网址主机和域名部分 www.baidu.com
var index = url.indexOf('//')+2;
console.log( url.slice( index, url.indexOf('/', index )  ) );

var filename = 'images/banner.jpg';

//1. 提取出文件扩展名 jpg
console.log( filename.slice(filename.lastIndexOf('.')+1) );

split 将字符串按指定字符转换为数组

返回的是数组,split支持''空字符串参数,howmany数值,返回所需数组最大长度。

语法

'苹果|桔子|香蕉'.split('|', howmany);//['苹果','桔子','香蕉']


示例

var filename = 'images/banner.jpg';
var arr = filename.split('.');
console.log(arr[arr.length-1]);

console.log( '苹果|桔子|香蕉'.split('|', 2) );//['苹果','桔子']

console.log('苹果桔子'.split('') );//['苹','果','桔','子']

toLowerCase toLocaleLowerCase 转换小写 转换本地小写

toLocaleLowerCase通常是你自己在原型链取同名函数覆盖,自定义自己的转换规则

console.log( 'ASADSADW'.toLowerCase()  );//asadsadw
console.log( 'ASADSADW'.toLocaleLowerCase()  );//asadsadw

推荐使用:toLowerCase

toUpperCase toLocaleUpperCase 转换小写 转换本地小写

toLocaleUpperCase通常是你自己在原型链取同名函数覆盖,自定义自己的转换规则

console.log( 'asadsadw'.toUpperCase()  );//ASADSADW
console.log( 'asadsadw'.toLocaleUpperCase()  );//ASADSADW

推荐使用:toUpperCase

repeat 将字符重复指定的次数 es6

//1. 替换手机中间部分为*号
var mobile = '18512345168';

var start = mobile.slice(0,3);
var end = mobile.slice(-4);
// console.log( start + '*'.repeat(4) + end );

//2.圆点自动补齐
var arr = ['abc','abcde','ssds','wewe','sds','fgf','fgf','fgf','fgf','fgf','fgf','fgf','fgf','fgf','fgf','fgf','fgf'];

//总长度
var total = 30;

//补齐符
var symbol = '.';

//自动补齐
for(var i=0;i<arr.length;i++){
  var num = total - arr[i].length - String(i+1).length;
  console.log( arr[i] + symbol.repeat(num) + (i+1) );
}

includes 查找是否包含某个字符串 es6

返回真和假

console.log('xianweb@qq.com'.indexOf('#'));//-1
console.log('xianweb@qq.com'.indexOf('@'));//7

console.log('xianweb@qq.com'.includes('#'));//false
console.log('xianweb@qq.com'.includes('@'));//true

replace 字符串替换

不使用正则替换,只能单次,并且区分大小写

语法

'字符串模板'.replace('被搜索的字符','用来替换的字符');

//示例
'hello'.replace('l','*');

//结果 he*lo

match、search 都是依赖使用正则表达式替换

localeCompare 比较两个字符的大小

字符串数字比较,

返回-1,前面的字符小于后面字符
返回0,前面的字符等于后面字符
返回1,前面的字符大于后面字符

var a = '1';
var b = '2';
console.log( a.localeCompare(b) ); // -1

var c = '1';
var d = '1';
console.log( c.localeCompare(d) ); // 0

var e = '2';
var f = '1';
console.log( e.localeCompare(f) ); // 1

字母比较

var a = 'a';
var b = 'b';
console.log( a.localeCompare(b) ); // -1

var c = 'a';
var d = 'a';
console.log( c.localeCompare(d) ); // 0

var e = 'b';
var f = 'a';
console.log( e.localeCompare(f) ); // 1

注意:中文是比较是采用unicode数字码比较,不是想要的效果。

Array数组对象

定义数组

  1. 构造函数方式定义
var arr = new Array();
arr[0] = '苹果';
arr[1] = '桔子';
console.log( arr );

  1. 构造函数参数赋值快速定义
var arr = new Array('苹果','桔子');
console.log( arr );

  1. 使用中括号简写定义(推荐)
var arr = ['苹果','桔子'];
console.log( arr );

数组的成员可以是任意数据类型

var arr = [ 
  1,
  true, 
  '苹果',
  undefined,
  null, 
  ['张三'],
  function(){
    return 10;
  },
  {
    id:10
  }
];

数组的长度

数组的长度可读可写

数组.length

示例

var arr = [];
arr.length = 10;//写
console.log( arr.length );//读 10

注意: 当我们使用length设置长度,如果产生空位,空位的值是undefined

var arr = ['a','b','c','d'];
arr.length = 2;
console.log( arr ); // ["a", "b"]
console.log( arr[100] );// 读 undefined
console.log(arr.length );// 2

数组和数组不能直接用加号相加,这样数组会自动转换为字符串

var arr1 = ['a','b'];
var arr2 = ['c','d'];

//隐式转换为字符串 ['a','b'] =>  a,b
console.log( arr1 + arr2 ); // a,bc,d

var str = '苹果,桔子,香蕉';
var arr = str.split(','); // ['苹果','桔子','香蕉']
console.log( arr );
console.log(  arr + '' ); // 苹果,桔子,香蕉

当给数组的length设置为0,那么就相当于清空数组。

//清空数组
console.log( ['苹果','桔子','香蕉'].length=0 );//[]

多维数组

如果数组的成员还是数组,就形成了多维数组。

var a = ['苹果','桔子']; //一维数组
var b = [ 
  ['苹果','桔子'], 
  ['青菜','肉'] 
]; 
//二维数组

//数组和对象相接口,非常类似于数据库记录集,类似于一个标准表格数据。
var data = [
  { id: 1, title: '标题1', author:'张三' },
  { id: 2, title: '标题2', author:'张三' },
  { id: 3, title: '标题3', author:'张三' }
]

数值键名会自动转换为字符串

//类数组对象
var obj = {
  0: '苹果',
  '1': '桔子',
  length: 2
}
console.log( obj[0], obj[1], obj['1'] );

数组的读写删操作

数组读取

var arr = ['苹果','桔子'];
console.log( arr[1] );

数组写入新成员

var arr = ['苹果','桔子'];
arr[2] = '香蕉'; //写入一个成员
console.log( arr );// ["苹果", "桔子", "香蕉"]

delete 数组删除成员

var arr = ['苹果','桔子','香蕉'];
delete arr[1];
console.log( arr );// ['苹果',empty,'香蕉']

注意:delete 删除数组成员并不会改变数组长度,而只是形参一个空位。

in 运算符

检查某个键名是否存在,适用于对象,也适用于数组。

var arr = ['苹果','桔子','香蕉'];
console.log( 0 in arr  );//true
console.log( 5 in arr  );//false

for...in 循环和数组的遍历

var arr = ['苹果','桔子','香蕉'];

//for 循环
for(var i=0;i<arr.length;i++){
  console.log( arr[i] );
}

//while 循环
var i=0;
while(arr[i]){
  console.log(arr[i]);
  i++;
}

//do while 循环
var i=0;
do{
  console.log(arr[i]);
  i++;
} while( i < arr.length );

//for in 循环 (不推荐)
for(var i in arr){
  console.log(arr[i]);
}

// forEach 高阶函数
arr.forEach( function( a,i,arr ){
  console.log(a,i,arr);
})


2019-7-17

forEach循环

forEach 不一定是数组特有的方法 不会循环空成员,比如:

var arr = [1,,,2,3,undefined];
//上面的数组用forEach循环,只会输出1,2,3,undefined

forEach 没有返回值,也就是内部加return没有返回值。

类数组对象转换为真正的数组对象

语法

var arr = Array.prototype.slice.call(类数组对象);

示例

//类数组对象
var obj = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3
};

//类数组转化为真正的数组
var arr = Array.prototype.slice.call(obj);

//因为已经数组了,所有使用forEach无妨
arr.forEach(function( item ){
  console.log( item );
})

因为字符串也是类数组,同样可以用上面的方法转成真正的数组

var str = '今天的天气不错';
var arr = Array.prototype.slice.call( str );
//输出 ["今", "天", "的", "天", "气", "不", "错"]

Array.isArray 检测是否是数组

var arr = ['a','b'];
console.log(  Array.isArray(arr)  );//true

对象

什么是对象?简单说,对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合。

对象是变量的集合(容器)

键值可以是任何数据类型

对象的属性之间用英文逗号分割

书写对象过程中常见问题

对象所有的键名都是字符串,所以加不加引号都可以,因为系统内部会转换为字符串

es6中引入了一种数据类型,叫symbol,它确保键名是唯一的,也可以使用symbol作为键名。

//问题1:尾部原则上不需要加英文逗号,但现代浏览器都能忽略
var obj = {
  foo: 'Hello',
  bar: 'World',
};

//问题2:键名和键值之间是英文冒号
var obj = {
  foo= 'Hello',
  bar= 'World',
};

//问题3:属性之间用英文逗号分割
var obj = {
  foo: 'Hello';
  bar: 'World';
};

//问题4:使用了中文的逗号
var obj = {
  foo: 'Hello',
  bar: 'World'
};

变量是传值传递,数组和对象因为是引用类型,所以它们是传址传递

//1.变量 => 传值传递
var a = 10;
var b = a;//10
a = 20;
console.log( a, b );// a = 20  b = 10

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//2. 对象 => 传址传递
var c = {
  name: '张三'
}

var d = c;

c.name = '李四';//对象写入

console.log( c, d );
//c = { name:'李四' }
//d = { name:'李四' }

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//3. 数组 => 传址传递
var a = ['苹果','桔子'];

var b = a;

a[1] = '香蕉';//数组写入

console.log( a, b );
//a = ['苹果','香蕉']
//d = ['苹果','香蕉']

表达式还是语句?

当对象的大括号{在首行首字母位置,如下,js引擎解析会产生歧义,为了避免下面的歧义,js规定,大括号出现在首行首字母位置,一律认为是语句,如果要解析为表达式,则需要用圆括号包裹对象即可。

//会被认为是语句
{
  name:'张三'
}

//会被认为是表达式
({
  name:'张三'
})

//表达式
var obj = {
  name:'张三'
}

eval函数

eval 函数会将字符串的内容当成表达式解析,注册改函数容易引起安全隐患,和性能开销比较大。

//1. eval 四则运算
var str='1*5+5';
console.log( str,  eval( str ) );

//2. eval 直接解析变量
var a = 10;
var str = 'a=30;';
console.log( str,  eval( str ) );


//3. eval 直接解析数组引用
var a = ['苹果','桔子'];
var str = 'a[1]';
console.log( str,  eval( str ) );

因为eval会带来安全问题和性能开销比较大,通常一些框架会屏蔽此函数,具体如下:

window.eval = null;

对象属性的操作

读取属性

  1. 通常点的形式读取
var obj = {
  name: '张三',
  'first-name': '李四',
  1: 'abc'
}
console.log(obj.name);//张三

  1. 通常中括号的形式读取
var obj = {
  name: '张三',
  'first-name': '李四',
  1: 'abc'
}
console.log(obj['name']);//张三
console.log(obj['first-name']);//李四
console.log(obj[1]);//abc

当键名是变量时,那么点调用的方式无效,应该使用中括号

var str = 'name';
var obj = {
  name: '张三',
  age: 20
}
str = 'age';
console.log(  obj[str] );// 20
console.log(  obj.str );//undefined,需要用[]

属性的赋值

点运算符和方括号运算符,不仅可以用来读取值,还可以用来赋值。

// 声明时直接填入属性
var person1 = {
  name: '张三',
  age: 20
}
console.log( person1 );

// 先声明一个对象,后填入属性
var person2 = {};
person2.name = '张三';
person2['age'] = 20;

console.log( person2 );

//对象比较是比较内存地址,不是值
console.log( person1 == person2 );//false

对象比较是比较内存地址,如下

// 声明时直接填入属性
var a = {
  name: '张三',
  age: 20
}
var b = a;//b等于a相当于b的内存地址指向了a
console.log( a == b  ); //true

中括号包裹键名,会起到解析为变量的作用

// 不加中括号
var str = 'name';
var a = {
  str:'张三',
  age: 20
}
console.log( a );//{ str:'张三',age:20 }

// 加中括号,会解析为变量
var str = 'name';
var a = {
  [str]:'张三',
  age: 20
}
console.log( a );//{ name:'张三',age:20 }

变量取名慎用name,在某些情况下会产生冲突。

Object.keys查看所有属性

Object.keys方法会将数组中所有的键名,放入到一个新数组中,返回数组。

当键名是symbol命名时,Object.keys会跳过symbol命名属性

var str = Symbol();
var a = {
  [str]: '张三',
  age: 20
}
var keys = Object.keys( a );
console.log( keys  );//['age']

//采用symbol数据类型命名的键名调用
var str = Symbol();
var a = {
  [str]: '张三',
  age: 20
}
console.log(a[str]);//张三

delete 命令删除对象属性

var str = Symbol();
var a = {
  [str]: '张三',
  age: 20
}
delete a[str];//删除symbol类型键名
delete a.age;//删除string类型键名
console.log( a );//{}

注意,删除一个不存在的属性delete不报错,而且返回true

var obj = {};
console.log( delete obj.name);//true

只有一种情况,delete命令会返回false,那就是该属性存在,且不得删除。

//1. 创建新对象创建新属性
var obj = Object.defineProperty( {},'name', {
  value: '张三',
  configurable: true
})
console.log( delete obj.name, obj );  //false


//2. 在原有对象基础上扩展新属性
var person = {
  name: '张三'
}
var obj = Object.defineProperty( person, 'age', {
  value: 56, //键值
  configurable: true, //configurable表示是否能被delete删除,false不能删除
  enumerable: true //enumerable表示是否能被Object.keys枚举,true可枚举
})
console.log( delete person.age, Object.keys(obj) );

delete命令只能删除对象本身的属性,无法删除继承的属性

var obj = {};
delete obj.toString // true
obj.toString // function toString() { [native code] }

in 运算符

in 运算符用于检查对象是否包含某个属性
in 运算符 继承的属性 也可以检测到,返回true
in 运算符 是浅查找属性,只支持一级属性验证。

var person = {
  name:'张三',
  info: {
    xueli: '本科'
  }
}
console.log( 'name' in person ); //true 
console.log( 'xueli' in person ); //false
console.log( 'xueli' in person.info ); //true

var obj = {
  name:'张三'
}
Object.defineProperty( obj, 'age', {
  value: 30,
  enumerable: false
})

console.log( obj );

console.log( 'name' in obj ); //true
console.log( 'toString' in obj ); //true
console.log( 'age' in obj );// true

for in 循环对象

  • for in 循环会跳过继承属性,比如toString
  • for in 循环会跳过不可枚举属性,比如设置enumerable: false
var obj = {
  name:'张三'
}
Object.defineProperty( obj, 'age', {
  value: 30,
  enumerable: true
})
for(var k in obj){
  console.log( k, obj[k] );
}

将对象的键值提取出来,装入一个新数组,模仿Object.keys功能

var index = 0;
var arr = []
for(var key in info){
  arr[index] = info[key];
  index++;
}
console.log( arr );

经典面试题

//查找字符重复的次数
var str = '一d你de你sqssd';

//对象方式
var info = {};
for( var i=0; i<str.length; i++ ){
  var val = str[i];
  if( val in info ){
    info [ val ] ++ ;
  }else{
    info [ val ] = 1;
  }
}
console.log( info );//{一: 1, d: 3, 你: 2, e: 1, s: 3, …}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~···

//查找重复最多的次数
var index = 0;
var firstVal = 0;

for(var key in info ){
  if( index == 0 ){
    firstVal = info[key];
  }else{
    if( firstVal < info[key]){
      firstVal = info[key];
    }
  }
  index++;
}
console.log( firstVal );// 3 

数组的方法

实例方法

变异和非变异的理解

  • 变异的方法:破坏了原始数组
  • 非变异的方法:不会破坏原始数组,产生新数组
  1. valueOf() 数组原始值 toString()将数组转化为字符串
var arr = ['苹果','桔子'];
console.log( arr.valueOf() ); // [1, 2, 3]
console.log( arr.toString() ); // 1, 2, 3
console.log( arr+'' ); // 隐式转换 1, 2, 3
console.log( arr.join(',') );// 1, 2, 3

  1. join() 将数组按指定的字符转换为字符串

返回新的字符串,不会破坏原始数组,非变异方法。

如果不提供参数,默认用逗号分隔。

var arr = ['苹果','桔子'];
console.log( arr.join('') ); //苹果桔子
console.log( arr.join('@') ); //苹果@桔子
console.log( arr.join() ); //苹果,桔子

var str = Array.prototype.join.call('hello', '-');
console.log( str );//h-e-l-l-o

  1. push() 向数组的尾部追加成员

返回数组最新的长度,该原始数组已经被添加新成员,是变异的方法。

var arr = ['苹果','桔子'];
arr[2] = '菠萝';
var result = arr.push('香蕉'); //执行过后返回数组最新的长度

console.log( result ); // 4
console.log( arr ); // ["苹果", "桔子", "菠萝", "香蕉"]

var arr = ['苹果','桔子'];
arr.push('香蕉','菠萝'); //一次性追加2个
arr.push( ['生菜','西红柿'] ); //追加一个数组
console.log( arr );// ['苹果','桔子','香蕉','菠萝', ['生菜','西红柿'] ]

  1. unshift() 向数组的开头追加成员

返回数组最新的长度,该原始数组已经被添加新成员,是变异的方法。

和 上面的push方法几乎一样,只是插入成员的位置不同。

var arr = ['苹果','桔子'];
arr.unshift('香蕉','菠萝'); //一次性追加2个
console.log(arr);//["香蕉", "菠萝", "苹果", "桔子"]

  1. pop() 删除数组最后一个成员

返回被删除成员的值,该方法会破坏原始数组,是变异的方法。

var arr = ['苹果','桔子'];
var result = arr.pop();

console.log( result );// 桔子
console.log( arr );// ['苹果']

  1. shift() 删除数组开头第一个成员

返回被删除成员的值,该方法会破坏原始数组,是变异的方法。

var arr = ['苹果','桔子'];
var result = arr.shift();

console.log( result );// 苹果
console.log( arr );// ['桔子']

  1. concat()

用于多个数组的合并,合并出一个新数组,不会破坏原始数组,是非变异的方法

var a = ['苹果','桔子'];
var b = ['芒果','西瓜'];
var arr = a.concat( b ); 
console.log( arr );// ['苹果','桔子','芒果','西瓜']


push()concat()的区别:

  1. push 返回数组新长度,concat 返回新数组
  2. push 变异的方法,concat 非变异的方法
  3. push 添加的是数组,会产生多维数组,concat 不会产生多维数组
  4. reverse() 反转数组

反转数组,返回已经破坏过后的原始数组,是变异的方法

var arr = [1,2,3];
arr.reverse();
console.log( arr ); // [3,2,1]

示例

//分步操作
var str1 = '今天的天气不错';
var arr = str1.split('');
arr.reverse();
var str1 = arr.join('');
console.log( str1 );

//链式操作
var str2 = '今天的天气不错'.split('').reverse().join('');
console.log( str2 );

  1. splice() 集删除、添加、修改功能的数组方法

该函数集删除、添加、修改功能的数组方法,会破坏原始数组,变异的方法。

起始位置,数值,支持负数,表示从后往前数。

删除的个数,数值,必填,如果设置为0,表示不删除。

返回被删除的数组

语法

数组.splice(起始位置,删除的个数, 新成员值1,新成员值2,....);

splice() 删除操作

//删除操作
var arr = ['苹果','桔子','芒果'];
arr.splice(1,1);
console.log( arr );

//1. 清空数组 splice
var arr1 = ['苹果','桔子','芒果'];
arr1.splice(0);//第2个参数省略,代表数组最大的长度
console.log(arr1);

//2. 始终删除第一个成员 splice
var arr2 = ['苹果','桔子','芒果'];
arr2.splice(0,1);
console.log(arr2);

//3. 始终删除最后一个成员 splice
var arr3 = ['苹果','桔子','芒果'];
arr3.splice(-1,1);
console.log(arr3);

//4. 始终只取数组最后两个成员 splice
var arr4 = ['苹果','桔子','芒果'];
arr4.splice(0, arr4.length-2);
console.log(arr4);

splice() 添加操作

注意:添加是在起始位置的前面追加

//添加操作

//1. 在桔子后追加香蕉1个成员
var arr1 = ['苹果','桔子','芒果'];
arr1.splice( 2, 0, '香蕉' );
console.log( arr1 );

//2. 在苹果后面追加火龙果、樱桃2个成员
var arr2 = ['苹果','桔子','芒果'];
arr2.splice( 1, 0, '火龙果','樱桃' );
console.log( arr2 );


//3. 在芒果后面追加数组['哈密瓜','西瓜']
var arr3 = ['苹果','桔子','芒果'];
arr3.splice( arr3.length, 0, ['哈密瓜','西瓜'] );//类似push方法
console.log( arr3 );

splice 修改操作,采用先删后加原则

//1. 在桔子修改为香蕉
var arr1 = ['苹果','桔子','芒果'];
arr1.splice(1,1,'香蕉');
console.log( arr1 );

//2. 在桔子修改为香蕉,芒果修改为西瓜
var arr2 = ['苹果','桔子','芒果'];
arr2.splice(1,2,'香蕉','西瓜');
console.log( arr2 );

  1. slice() 分割数组

slice 按照起始位置和结束位置分割出一个新数组,它不会破坏原始数组,是非变异的方法,返回新数组。

起始位置,数值,可以是负数,表示从后开始算,-1 表示倒数第一个

结束位置,数值,可以是负数,表示从后开始算,-1 表示倒数第一个

省略结束位置,表示到数组末尾(相当于数组的长度)。

语法

数组.slice(起始位置,结束位置)

示例

var arr = ['苹果','桔子','香蕉','菠萝','西瓜'];

//1. 提取第一个成员
console.log( arr.slice(0,1) );

//2. 提取第桔子和香蕉
console.log( arr.slice(1,3) );

//3. 始终提取最后一个成员
console.log( arr.slice(-1) );

//4. 始终提取除第一个和最后一个成员
console.log( arr.slice(1,-1) );

//5. 始终提取最后两个成员
console.log( arr.slice(-2) );

示例求学生三门成绩的总分、平均分、最低分、最高分

    <style>
        * {
          margin: 0;
          padding: 0;
          box-sizing: border-box;
        }
        body{
          padding: 20px;
        }
        table{
          border-collapse:collapse;
          border: 1px solid #ccc;
        }
        th,td{
          padding: 10px;
        }
        tbody tr:nth-child(odd) td{
          background-color: #eee;
        }
      </style>
  <script>
  var data = [
    { id: 1, name:'张三', score: [ 78, 88, 75] },
    { id: 2, name:'李四', score: [ 66, 79, 85] }
  ];

  var temp = `<table cellspacing="0" border="1">
    <thead>
      <tr>
        <th>学号</th>
        <th>姓名</th>
        <th>语文</th>
        <th>数学</th>
        <th>外语</th>
        <th>总分</th>
        <th>平均分</th>
        <th>最低分</th>
        <th>最高分</th>
      </tr>
    </thead>
    `;
  
  for(var i=0;i<data.length;i++){

    var score = data[i].score;
    var sum = score.reduce( function( prev, next ){ 
      return prev + next;
    });//总分
    var min = Math.min.apply( null, score );//最低分
    var max = Math.max.apply( null, score );//最高分
    var avg = (sum/3).toFixed(1);//平均分

    temp += `
    <tbody>
      <tr>
        <td>${data[i].id}</td>
        <td>${data[i].name}</td>
        <td>${score[0]}</td>
        <td>${score[1]}</td>
        <td>${score[2]}</td>
        <td>${sum}</td>
        <td>${avg}</td>
        <td>${min}</td>
        <td>${max}</td>
      </tr>
    </tbody>
    `;
  }

  temp += '</table>';

  document.write( temp );

  var arr = [2,3,5,6,8,9];
  var num = Math.max.apply( null, arr );
  

  console.log( num );

  </script>

分页四要素

  1. 当前页 page
  2. 总个数 total
  3. 每页多少个 perpage
  4. 总页数 totalpage

sort() 对数组成员进行排序,默认是按照字典顺序排序,排序后,原数组将被改变,变异的方法。

//数字排序
var arr = [ 2,6,1,9, 4];
arr.sort();
console.log( arr ); // [1, 2, 4, 6, 9]

//数字排序不正确,是按字符串排序
var arr = [ 2, 6, 1, 9, 4, 12, 24];
arr.sort();
console.log( arr ); // [1, 12, 2, 24, 4, 6, 9]

//字符串排序
var arr = [ 'b', 'a', 'c', 'd', 'ab', 'bc'];
arr.sort();
console.log( arr ); //["a", "ab", "b", "bc", "c", "d"]


以上排序有局限性,比如数字它是字符来排序的,而且也不方便升序、降序切换

我们可以通过设置一个回调函数使得排序更加精确

语法

数组.sort( function( prev, next ){
  return prev - next;
})

数值排序示例

//数值排序
var arr = [ 2, 6, 1, 9, 4, 12, 24];
var flag = -1;// 1 为升序  -1 降序
arr.sort( function( a, b ){
  return ( a - b ) * flag;
});
console.log( arr ); 

字符串排序

//字符串排序
var arr = [ 'b', 'a', 'c', 'd', 'ab', 'bc' ];
var flag = 1; // 1 为升序  -1 降序

arr.sort( function( a, b ){
  return a.localeCompare( b ) * flag;
})

console.log( arr ); 

数组也可以用来替代条件语句输出

var day = new Date().getDay();//0 - 6
var week = ['日','一','二','三','四','五','六'];
console.log('今天是星期' + week[day] );

map() 将数组的所有成员依次传入参数函数,然后把每一次的执行结果组成一个新数组返回,它是非变异的方法。

var arr = [ 1, 2, 3, 4, 5];
var newArr = arr.map(function( item ){
  return item * 2;
})

console.log( newArr );// [ 2, 4, 6, 8, 10 ]

//取出偶数成员
var arr = [ 1, 2, 3, 4, 5];
var newArr = arr.map(function( item ){
  if(item % 2 == 0) {
    return item;
  }
})
console.log( newArr );//[undefined, 2, undefined, 4, undefined]

//map中this指向第二个参数,下图也就是arr数组

var arr = ['a', 'b', 'c'];
var newData= [0, 2].map(function ( item ) {
  return this[ item ];
}, arr);

console.log( newData ); // ['a','c']

forEach()map方法很相似,也是对数组的所有成员依次执行参数函数,forEach方法不返回值,只用来操作数据。

示例

var arr = [ 1, , 3, , 5];
arr.forEach(function( item, index, arr ){
  console.log( item, index, arr );
})

forEachmap的区别

  • forEach 没有return返回值,它会跳过空位
  • mapreturn返回值,它会跳过空位

filter() 方法用于过滤数组成员,满足条件的成员组成一个新数组返回,非变异的方法。

//查找出不及格的分数
var score = [ 50, 70, 58, 62, 80];
var newScore = score.filter( function(item){
  return item < 60;
})

console.log( newScore );//[50, 58]

//也可以利用排除法删除
var arr = [ 50, 70, 58, 62, 80];
arr = arr.filter( function(item){
  return item != 62;
})
console.log( arr );//[ 50, 70, 58, 80];

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 一、 入门 1、 JS代码书写的位置 写在行内 写在script标签中 写在外部js文件中,在页面引入 注意点: ...
    宠辱不惊丶岁月静好阅读 844评论 0 0
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,204评论 0 4
  • 9.正则表达式 首先,js定义了RegExp()构造函数,用来创建表示文本匹配模式的对象。这就是正则表达式。正则表...
    我就是z阅读 631评论 0 5
  • js组成部分:1、ECMAscript 核心语法2、DOM3、BOMjs书写方式:1、行内2、外联 、在head...
    每天进步一点点5454阅读 389评论 0 0
  • 我想象着他的忧愁 歪歪斜斜地走 火苗攒簇着拥向烟头 带烟的夹克 冷不丁铺在身后 像一场大雨隔断深秋 像宠了一座江山...
    ___零点阅读 244评论 0 4