JavaScript学习笔记(一)

写在前面:计划先跟着廖雪峰的JavaScript教程学习,对Js有个大致的了解后再看看JavaScript的官方教程

一、快速入门

1.“由于浏览器的安全限制,以file://开头的地址无法执行如联网等JavaScript代码。。。”,最终还是要搭建Web服务器(如Tomcat等)来正常执行JavaScript代码。

2.在Firefox浏览器上尝试执行js代码,可以在页面上右键选择查看元素然后选择控制台,或者浏览器右上角选择Web开发者——>切换工具箱——>选择控制台,在该面板直接输入js代码并运行如下:
在这里插入图片描述

高级调试技巧参考

3.练习:打开新浪首页,并且打开Web控制台,输入console.log('Hello');回车执行该代码得到的结果是Hello。

4.“JavaScript引擎自动加分号在某些情况下会改变程序的语义”,最好养成在每个语句最后加上符号;的习惯;并且缩进一般也是4个空格;“过多的嵌套会增加代码的复杂程度,需要将部分代码抽出来作为函数调用”。

5.字符串是以单引号’或双引号"括起来的任意文本,这和python的规定一致。

6.(1)注意:“JavaScript允许对任意数据类型做比较”,有两种比较符(设计缺陷),=,前者会自动进行数据类型转换(false0;//成立),后者会先判断数据类型是否一致,然后比较具体的值(false=0; // 不成立),所以“不要使用==比较,始终坚持使用===比较”;

(2)除此之外,不能用NaN===NaN;判断一个数是否是NaN,只能通过函数isNaN()判断是否是NaN。

(3)“要比较两个浮点数是否相等,只能计算它们之差的绝对值,看是否小于某个阈值”:

Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true
1 / 3 === (1 - 2 / 3); // false

7.undefined表示值未定义,用于判断函数参数是否传递,用索引访问数组越界时返回undefined。

8.js的数组可以包含任意数据类型,有两种创建数组的方式,“考虑代码可读性,最好用第一种”:

(1)直接用[]包含,例:[1, 5.7, true, null]

(2)通过Array数组实现,例:new Array(1, 3, 5);

9.“JavaScript的对象是一组由键-值组成的无序集合”,在表达形式上类似于Python的字典类型(但其实读到后面具体介绍对象的部分,js的对象更适合与Python的对象类比,以免陷入混乱),但js的键(属性)默认都是字符串类型,而且用对象变量.属性名来获取一个对象的属性(类似于Java中获取静态变量)。

10.js中“变量名是大小写英文、数字、$和_的组合,且不能用数字开头,变量名也不能是JavaScript的关键字,如if、while等,变量名最好不用中文”,用var语句声明变量,例:var $a = 5;注意:“同一个变量可以反复赋值,而且可以是不同类型的变量,但是要注意只能用var声明一次”。js有三种声明变量的方式,参考学习博客

11.js和Python一样都是动态语言——“变量本身类型不固定”,java是静态语言——“在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错”。

12.未使用var声明的变量是全局变量,“在strict模式下运行的JavaScript代码,强制通过var声明变量,未使用var声明变量就使用的,将导致运行错误”,在js代码的第一行写:‘use strict’;启动strict模式。

13.看到strict模式时尝试运行在strict模式下不能定义全局变量的示例代码,结果没有报错,切换到控制台也不报错,初步判断可能是Firfox浏览器版本问题,但检查后我的浏览器是最新版的,换成Google浏览器(最新版)试了一下也没有报错,黑人问号???后来看了一下课程下面的评论,有人说是“在控制台上运行的每一个语句都是一个block,而在一个单独的block中,‘use strict’才有效”,感谢老兄,解决了,之前我都是逐个语句输入到控制台运行的(菜鸡一只),把示例代码一起输入控制台成功报错——引用错误ReferenceError(在作用域中找不到):
在这里插入图片描述
14.字符串部分注意转义字符的用法(和java格式字符串等类似),”如字符串中同时有符号’和符号"时,可用转义字符处理,如:‘I’ m “OK”!’’;“,用’\x##‘的形式表示ASCII字符,如’\x41’等同于’A’;用’\u####‘的形式表示Unicode字符,如’\u4e2d\u6587’等于’中文’。

15.多行字符串有两种表达方式,用\n或反引号的形式,示例如下:

'这是一个\n多行\n字符串';

`这是一个
多行
字符串`;

16.有两种方法连接多个字符串,用符号+或ES6模板字符串(反引号和${变量}组合),示例如下:

var name = '小明';
var age = 20;
var message = '你好, ' + name + ', 你今年' + age + '岁了!';
alert(message);

var name = '小明';
var age = 20;
var message = `你好, ${name}, 你今年${age}岁了!`;
alert(message);

17.注意:“字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但也没有任何效果”,示例如下:

var s = 'Test';
s[0] = 'X';
alert(s); // s仍然为'Test'

18.js中字符串的一些常用方法和java中的一样,调用教程列举的方法不会改变字符串本身,而是返回新的字符串。获取字符串的长度,如:

var a = "Hello";
a.length; // 5

方法substring的两个参数可以类比左闭右开区间。

19.获取数组的长度可以访问属性length,“直接给数组的length属性赋一个新的值会导致数组大小的变化:”

var arr = [1, 2, 3];
arr.length; // 3
arr.length = 6;
arr; // arr变为[1, 2, 3, undefined, undefined, undefined]
arr.length = 2;
arr; // arr变为[1, 2]

20,“对数组的索引进行赋值会直接修改这个数组,但如果索引超过了范围,同样会引起数组大小的变化:”

var arr = [1, 2, 3];
arr[5] = 'x';
arr; // arr变为[1, 2, 3, undefined, undefined, 'x']

注意:“不建议直接修改数组的大小,访问索引时要确保索引不会越界”。

21.类似于字符串,数组可以通过调用方法indexOf来搜索一个指定的元素的位置。

22.“数组的方法slice对应字符串的方法substring,它截取数组的部分元素,然后返回一个新的数组,如果方法slice没有参数,就是复制该数组,但复制的数组和被复制的数组不相等(=),因为不是同一个对象”,数组之间不能用符号=判断是否相等(待学习)。

23.方法push或unshift向数组的末尾或头部添加若干元素,同时返回数组的长度,方法pop或shift则把数组的最后或头部一个元素删除掉,空数组调用pop或shift方法不会报错,而是返回undefined。

24.方法splice可以从数组指定的索引开始删除若干元素(可选项),然后再从该位置添加若干元素(可选项),同时返回删除的元素(数组形式),示例如下:

var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回Array(3)['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']

25.“方法concat将当前数组和另一个数组连接起来,并返回一个新的数组,不会修改当前数组,该方法可以接收任意个元素和数组,并且自动把数组拆开,然后全部添加到新的数组里”,示例代码:

var arr = ['A', 'B', 'C'];
arr.concat(1, 2, [3, 4]); // ['A', 'B', 'C', 1, 2, 3, 4]

26.“join方法把当前数组的每个元素都用指定的字符串连接起来,然后返回连接后的字符串,如果数组的元素不是字符串,将自动转换为字符串后再连接”,示例代码:

var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'

27.练习1,如何通过索引取到500这个值:

'use strict';
var arr = [[1, 2, 3], [400, 500, 600], '-'];
var x = arr[1][1];
console.log(x); // x为500

28.练习2,在新生欢迎会上,你已经拿到了新同学的名单,请排序后显示:欢迎XXX,XXX,XXX和XXX同学!:

'use strict';
var arr = ['小明', '小红', '大军', '阿黄'];

arr.sort();
console.log(`欢迎${arr[0]}${arr[1]}${arr[2]}${arr[3]}同学!`);

console.log(`欢迎${arr.slice(0,3).join(',')}${arr[3]}同学!`);

var last = arr.pop();
console.log(`欢迎${arr.join(',')}${last}同学!`);

29.js的对象“最后一个键值对不需要在末尾加,,如果加了,有的浏览器(如低版本的IE)将报错”。

30.“如果对象的属性名包含特殊字符(不是有效的属性名,包含除了大小写字母、数字、符号$-的其他字符?(待解决)),就必须用''括起来,访问这个属性也无法使用.操作符,必须用['xxx']来访问;此外可以用.操作符或['×××']来访问有效属性名”,示例代码:

var xiaohong = {
    name: '小红',
    'middle-school': 'No.1 Middle School'
};

xiaohong['middle-school']; // 'No.1 Middle School'
xiaohong['name']; // '小红'
xiaohong.name; // '小红'

31.js的对象访问不存在的属性不报错,而是返回undefined;因为js的对象是动态的,所以可以随意给一个对象添加或删除属性(执行delete语句,delete 对象名.属性名),删除不存在的属性也不会报错(返回的都是true)。

32.用in判断属性是否在对象中,用方法hasOwnProperty判断属性是否是对象自己的而不是继承得到的,示例代码:

var xiaoming = {
    name: '小明',
    birth: 1990,
    school: 'No.1 Middle School',
    height: 1.70,
    weight: 65,
    score: null
};
'name' in xiaoming; // true
'grade' in xiaoming; // false

var xiaoming = {
    name: '小明'
};
xiaoming.hasOwnProperty('name'); // true
xiaoming.hasOwnProperty('toString'); // false

33.因为对js的对象讲解部分存在一点疑惑,翻评论的时候看到通过for循环正确访问对象的所有属性的方法,示例代码如下,for循环取出的prop都是字符串类型的,所以只能用对象名[prop]的方式访问属性值,而不是对象名.prop的形式(这样得到的结果是undefined):

var xiaoming = {
    name: '小明',
    birth: 1990,
    school: 'No.1 Middle School',
    height: 1.70,
    weight: 65,
    score: null
};

for(var prop in xiaoming){
	console.log(`${prop}:${xiaoming[prop]}`);
}

//结果:
name:小明
birth:1990
school:No.1 Middle School
height:1.7
weight:65
score:null

34.对象部分小结:js中对象的所有属性都是字符串,只是创建对象时没有加引号,所以访问属性值时存在对象名[‘属性名’]的表达形式,以及判断属性是否存在于对象中时也是以'属性名' in 对象名的形式进行判断,hasOwnProperty方法的参数也应该是'属性名'的形式。

35.注意:“在多个if...else...语句中,如果某个条件成立,则后续就不再继续判断了,此外,js把if条件判断语句的结果是nullundefined0NaN和空字符串''的视为false,其他值一概视为true”。

36.条件判断部分练习代码:

'use strict';

var height = parseFloat(prompt('请输入身高(m):'));
var weight = parseFloat(prompt('请输入体重(kg):'));
var bmi = weight / (height * height);
if (bmi <= 18.5){
    alert('过轻');
}else if (bmi < 25.0){
    alert('正常');
}else if (bmi < 28.0){
    alert('过重');
}else if (bmi < 32.0){
    alert('肥胖');
}else{
    alert('过于肥胖');
}

37.循环部分练习,利用for循环计算1 * 2 * 3 * ... * 10的结果:

'use strict';

var x = 1;
var i;
for (i = 2; i <= 10; i++) {
    x = x * i;
}
if (x === 3628800) {
    console.log('1 x 2 x 3 x ... x 10 = ' + x);
}
else {
    console.log('计算错误');
}

38.“由于数组也是对象,而它的每个元素的索引(0,1,2)被视为对象的属性(’0‘,’1‘,’2‘),因此,for ... in循环可以直接循环出数组的索引,示例代码:”

var a = ['A', 'B', 'C'];
for (var i in a) {
    console.log(i); // '0', '1', '2'
    console.log(a[i]); // 'A', 'B', 'C'
}

注意:“for ... in对数组的循环得到的是字符串而不是数字”。

39.练习利用循环遍历数组中的每个名字,并显示Hello, xxx!

'use strict';
var arr = ['Bart', 'Lisa', 'Adam'];

console.log('正序遍历:');
for (var i in arr) {
    console.log(`Hello,${arr[i]}!`);
}
console.log('\n');

for (var i = 0; i < arr.length; ++i) {
    console.log(`Hello,${arr[i]}!`);
}
console.log('\n');

var w = 0;
while(w < arr.length) {
    console.log(`Hello,${arr[w]}!`);
    ++w;
}

console.log('\n反序遍历:');
for (var i = arr.length - 1; i >= 0; --i) {
    console.log(`Hello,${arr[i]}!`);
}
console.log('\n');

var w = arr.length - 1;
while(w >= 0) {
    console.log(`Hello,${arr[w]}!`);
    --w;
}

40.初始化Map有两种方法:用一个二维数组初始化;或者直接初始化一个空Map,然后调用set方法添加键值对,get方法得到对应键的值,has方法判断对应键是否存在,delete方法删除对应键值对,示例代码如下:

var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95

var m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined

41.Set只存储键,并且没有重复的键,重复元素在自动被过滤,方法add将元素添加到Set中,方法delete将元素从Set中删除。注意:“Map和Set是ES6标准新增的数据类型,根据浏览器的支持情况决定是否要使用”。

42.“ArrayMapSet都属于iterable类型,具有iterable类型的集合可以通过for ... of循环来遍历”,对数组(也是对象)a而言,for (var x in a)循环得到的是数组的索引(’0‘,’1‘…),而for (var x of a)循环得到的是数组的元素值,如果意外给数组a增加了属性,如a.name = 'erin';,前者在循环时会得到’name’,后者则仍然得到的是数组本身的元素,没有’erin’;对Map类型的m而言for (var x of m)循环得到的x是一个由键值对组成的数组。

43.对于iterable类型内置的forEach函数,它接受一个回调函数,如果不需要使用回调函数中的某些参数则可以省略,相关代码如下,但经过试验,回调函数的参数对应的内容顺序是不变的,如将Map的value和key参数交换顺序,交换后的key对应的是键值对中的值而不是键,value对应的是键。

// 数组调用forEach方法
var a = ['A', 'B', 'C'];
// element是当前元素的值,index是当前索引,array是数组对象本身
a.forEach(function(element, index, array){
    console.log(element + ' index = ' + index);
});

// 集合Set调用forEach方法
var s = new Set(['A', 'B', 'C']);
// element和sameElement都是元素本身,set是集合对象本身
s.forEach(function (element, sameElement, set) {
    console.log(element);
});

// 映射Map调用forEach方法
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
// value是键值对中的值,key是键值对中的键,map是映射对象本身
m.forEach(function (value, key, map) {
    console.log(value);
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值