[TOC]
运算符和表达式
-
算术运算
一个不为0的正数除以0等于 Infinity
一个不为0的负数数除以0等于 -Infinity
0 / 0 为 NaN
console.log(1 + 2 * 3); //7
console.log(1 + 3 % 2); //2
console.log("" + 3 % 2); //'1'
console.log(+"" + 3 % 2); //1
console.log(+{} + ""); //'NaN'
console.log(100 % 4 / 0); //NaN
console.log(null / null); //NaN
var a;
console.log(a + {} + 123);// 'undefined[object Object]123'
console.log(1 + "" + 2 + 3);//'123'
console.log({} * null); //NaN
console.log(+"" + 100); //100
console.log('\n\t\f' / 2 +100); //100
console.log('b' + 'a' + (+'a') + 'a');//'baNana'
复制代码
0 + null + true+ [] + undefined + null + 10 + [] + 'js学习'
在控制台打印什么
1undefinednull10js学习
- 下面代码输出什么
var a = 'abc' + 123 + 456; //'abc123456'
var b = '456' - '123'; //333
var c = 100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false; //'NaNTencentnull9false'
console.log(a,b,c)
复制代码
- 下面代码弹出什么
var str = 'abc123';
var num = parseInt(str);
if(num == NaN) {
alert(NaN);
} else if(num == 123) {
alert(123);
} else if(typeof num == 'number') {
alert('number');
} else {
alert('str');
}
复制代码
'number'
-
自增自减运算(难点)
优先级的运算细节
- 从左到右依次查看
- 如果遇到操作数,将数据直接取出
- 如果遇到相邻的两个运算符,并且左边运算符的优先级大于等于右边的运算符,则直接运算左边的运算符
参考中缀表达式代码
- 计算下面代码的输出结果
var x = 1;
var y = x + x++ * ++x;
console.log(y) //4
复制代码
var x = 1;
var y = x++ + ++x + x++ * ++x + ++x;
console.log(y) // 25
复制代码
var x = 1;
var y = x + ++x * ++x + x;
console.log(y) //10
复制代码
var x = 1;
var y = x + x++ * (x = x + x++ * ++x) + x;
console.log(y) //21
复制代码
-
比较运算符
-
下面的相等运算符会在浏览器中打印什么
'0' == true // false
[1] == [1] // false
[1] == 1 // true
null == false // false
null == undefined // true
NaN === NaN // false
+0 === -0 // true
Object.is([], []) // false
Object.is(-0, +0) // false。见SameValue
Object.is(NaN, NaN) // true。见SameValue
var arr = [NaN, 0, +0]
arr.indexOf(-0) // 1。见===
arr.indexOf(NaN) // -1。见===
arr.includes(-0) // true。见SameValueZero
arr.includes(NaN) // true。见SameValueZero
复制代码
- 下面的代码输出什么
console.log('1' >= 10); //false
console.log('2' > true); //true
console.log(NaN > 0); //false
console.log(3 > {}); //false
console.log(null > -1); //true
console.log(undefined > -1);//false
复制代码
-
逻辑运算符
-
打印下面代码输出结果
var x = 1;
console.log(x++ >= 1 && x++ >=2 && x++ >= 4 && x++ >= 4); //false
console.log(x);//4
复制代码
- 打印下面代码输出结果
console.log(0 || null || undefined || 1 || null || NaN); //1
复制代码
- 判断是否是闰年
4年一闰,百年不闰;400年一闰
console.log(year % 4 === 0 && year % 100 !== 0 || year % 400 === 0);
复制代码
- 利息计算器,分别存放本金,月数,年利率,计算利息 如果本金存放超过了10万,年利率上浮20%(比如年利率为4%,上浮后的年利率为4% * 1.2)
var money = 200000,
month = 12,
rate = 4;
money > 100000 && (rate = rate * 1.2);
var lixi = money * rate / 100 / 12 * month;
console.log(lixi);
复制代码
-
三目运算符
-
下面的代码输出什么
var x = 1;
x = x++ >= 1 ? x++ * x++ : ++x * ++x;
console.log(x);//6
复制代码
基本数据类型
- 能输出”1″的有哪些
A alert(1)
B console.log(parseInt(1.3))
C console.log(1)
D console.log(isNaN(1))
E console.log(parseInt("1"))
复制代码
A
- 下面结果是”undefined”的是
A console.log(alert(1))
B typeof undefined
C console.log(parseInt(undefined))
D isNaN(undefined)
复制代码
没有返回值,默认返回undefined,是undefined类型 答案B
- 下面结果能得到true的是
A isNaN(null)
B isNaN(parseInt(null))
C new Number(null)
D parseFloat(null)
复制代码
B
- 输出下面程序的结果
parseInt("") //NaN
Number("") //0
isNaN("") //false
parseInt(null)//NaN
Number(null) //0
isNaN(null) //false
parseInt("12px")//12
Number("12px")//NaN
isNaN("12px") //true
复制代码
- 下面程序输出结果是
if(isNaN(NaN) == "") {
console.log("前端")
} else {
console.log("培训")
}
复制代码
培训
引用类型
- 下面代码在控制台打印什么
var obj = {
num:100,
m:obj.num * 10
}
复制代码
控制台打印值:
VM1829:3 Uncaught TypeError: Cannot read property 'num' of undefined
at <anonymous>:3:11
因为先计算值,在把值和属性关联(普通变量的赋值也是这样的)
在值得计算中,此时obj还没有和这个对象关联,而是undefined
复制代码
- 下面的程序输出什么
let n = [10,20];
len m = n;
let x = m;
m[0] = 100;
x = [30,40];
x[0] = 200;
m = x;
m[1] = 300;
n[2] = 400;
console.log(n, m, x);
复制代码
的输出结果:
n: 100 20 400
m: 200 300
x: 200 300
- 下面的程序输出什么
let x = [1, 2, 3];
let y = x;
let z = [4, 5, 6];
y[0] = 10;
y = z;
z[1] = 20;
x[2] = z = 30;
console.log(x, y, z);
复制代码
x [10 2 30]
y [4 20 6]
z 30
- 下面的程序输出什么
let a = {
n:1
};
let b = a;
a.x = a = {
n:2
};
console.log(a.x);
console.log(b);
复制代码
undefined
{n:1,{n:2}}
- 下面的代码输出什么
var user1 = {
name:"u1",
address: {
country:"中国",
city:"哈尔滨"
}
};
var user2 = {
name:"u2",
address:user1.address
};
user2.name = "user2";
user2.address.city = "成都";
console.log(user1.name,user2.name); //u1,user2
console.log(user1.address.city,user2.address.city) //成都 成都
复制代码
var obj1 = {
a: "123",
b: "456",
sub: {
s1: "abc",
s2: "bcd"
}
};
var obj2 = obj1;
obj2.sub = {
s1: "s",
s2: "ddd"
};
console.log(obj1.sub.s1, obj2.sub.s1); //s, s
复制代码
- 下面的代码输出什么
var a = 0;
var b = a;
b++;
alert(a); //0
var o = {};
o.a = 0;
var b = o;
b.a = 10;
alert(o.a); //10
复制代码
流程控制语句
if判断
- 下面的代码输出什么
if (!x) {
x = 1;
}
if (x++ >= 1) {
var x;
x++;
} else if (++x >= 2) {
x++;
} else {
x--;
}
console.log(x);//3
复制代码
- 提示用户输入一个三位数,若不是三位数,则提示用户输入有误,若是三位数,则判断该数能否被13整除
var result = +prompt("请输入一个三位数");
if(isNaN(result) || result < 100 || result >999) {
console.log('输入有误');
} else {
if(result % 13 === 0) {
console.log('能被13整除')
} else {
console.log('不能被13整除');
}
}
复制代码
- 让用户输入一个成绩(0-100),判断这个成绩属于哪个范围并输出结果(A:90-100 B:70-89 C:60-69 D:40-59 E:0-39),若用户输入的不是0 -100之间的数字,则判断用户输入有误
var score = +prompt("请输入成绩");
if (isNaN(score) || score > 100 || score < 0) {
alert('输入有误');
} else if(score >= 90){
alert('A');
} else if(score >= 70) {
alert('B');
} else if(score >= 60) {
alert('C');
} else if(score >= 40) {
alert('D');
} else {
alert('E');
}
复制代码
- 根据世界卫生组织推荐的计算方法,
男性标准体重计算方法为(身高cm – 80) * 70%
女性标准体重的计算方法为(身高cm – 70) * 60%
标准体重正负10%为正常体重,低于标准体重的10%为过瘦,高于标准体重的10%为过胖
编写程序,让用户输入性别,身高,体重,判断用户的健康状态
健康状况有3种:
1)你的体重正常,请继续保持
2)你的身体偏瘦,请加强营养
3)你的身体偏胖,请加强锻炼
var gender = prompt('请输入你的性别(男,女)');
var height = +prompt('请输入你的身高(cm)');
var weight = +prompt('请输入你的体重(kg)');
if (isNaN(height) || isNaN(weight) || gender !== '男' && gender !== '女') {
alert('输入有误');
} else {
var standWeight;
gender === '男' && (standWeight = (height - 80) * 0.7);
gender === '女' && (standWeight = (height - 70) * 0.6);
if (weight > standWeight * 1.1) {
alert('你的身体偏胖,请加强锻炼');
} else if (weight >= standWeight * 0.9) {
alert('你的体重正常,请继续保持');
} else {
alert('你的身体偏瘦,请加强营养 ');
}
}
-------------------------------------里面的判断还可以这样写---------------------------
if(weight < standWeight * 0.9) {
alert('你的身体偏瘦,请加强营养')
} else if(weight <= standWeight * 1.1) {
alert('你的体重正常,请继续保持')
} else {
alert('你的身体偏胖,请加强锻炼')
}
-------------------------------------里面的判断还可以这样写---------------------------
if(weight < standWeight * 0.9) {
alert('你的身体偏瘦,请加强营养');
} else if(weight > standWeight * 1.1) {
alert('你的身体偏胖,请加强锻炼');
} else {
alert('你的体重正常,请继续保持');
}
复制代码
- 若用户的理财金额在50万元以下,则每年的受益按照4%计算
若用户的理财金额在50万元以上(包括50万元),则每年的受益按照4.5%计算
若用户的理财金额超过200万,除了理财受益外,还有额外给予用户受益金额的10%
编写程序,让用户输入理财金额和理财年限,计算到期后的受益
var money = +prompt("请输入金额");
var year = +prompt("请输入年限");
if(isNaN(money) || isNaN(year) || money <= 0 || year <= 0) {
alert('输入非法');
} else {
var income;
if(money < 500000) {
income = money * 0.04 * year;
} else if(money < 2000000) {
income = money * 0.045 * year;
} else {
income = money * 0.045 * year * 1.1;
}
}
alert(income);
复制代码
- 编写一个用户和计算机的猜拳游戏,用户输入剪刀,石头,布,与计算机的出拳进行比较,判断胜负
var fist = prompt('请输入你的出拳:石头,剪刀,布');
if (fist !== '石头' && fist !== '剪刀' && fist !== '布') {
alert('输入不合法');
} else {
var ran = Math.random();
var computfist;
if (ran < 0.3333) {
computfist = '石头'
} else if (ran < 0.6666) {
computfist = '剪刀';
} else {
computfist = '布';
}
if(fist === '石头' && computfist === '剪刀' || fist === '剪刀' && computfist === '布' ||
fist === '布' && computfist === '石头') {
alert(`你出拳是${fist},计算机出拳是${computfist},你胜利了`)
} else if(fist === computfist) {
alert(`你出拳是${fist},计算机出拳是${computfist},平局`);
} else {
alert(`你出拳是${fist},计算机出拳是${computfist},你输了`);
}
}
复制代码
for循环
- 下面的for循环输出什么
for (var i = 10; i > 4; i -= 2) {
if (i < 7) {
i++;
} else {
i--;
}
}
console.log(i) //4
复制代码
- 下面的循环输出什么
for (var i = 0; i < 10; i++) {
if (i >= 2) {
i += 2;
continue;
}
if (i >= 6) {
i--;
break;
}
i++;
console.log(i); //1
}
console.log(i); //11
复制代码
- 下面的循环输出什么
var i = 0;
while(i < 10) {
if(i === 3) {
i++;
continue;
}
console.log(i);
i++;
}
console.log("循环介绍", i);
复制代码
0 1 2 4 5 6 7 8 9
循环结束 10
循环的应用(重点)
累计问题(定义变量
sum
)
查找问题(定义变量isFind
)
- 求 1到100所有数字累加之和
- 1到10数字相乘
- 1到100所有奇数相加
- 135到145之间是否存在能整除26的数字
- 打印135到185之间所有能整除26的数字
- 打印135到185之间第一个能整除26的数字,如果不存在,输出不存在
查找问题常用代码套路//
var isFind = false;
for (var i = 135; i <= 185; i++) {
if(i % 26 === 0) {
console.log(i);
isFind = true;
break;
}
}
if(!isFind) {
console.log('不存在');
}
复制代码
- 判断一个数是不是素数
var isFind = false;
for (var i = 2; i < num; i++) {
if (num % i === 0) {
isFind = true;
break;
}
}
if(isFind || num <= 1) {
console.log('不是素数');
} else {
console.log('素数');
}
复制代码
- 打印1到100之间的所有素数
for (var i = 1; i <= 100; i++) {
var isFind = false;
for (var j = 2; j < i; j++) {
if(i % j === 0) {
isFind = true;
break;
}
}
if(!isFind && i > 1) {
console.log(i);
}
}
复制代码
-
在控制台输出100个
*
-
让用户输入
*
号的数量,然后输出对应数量的*
-
输出一个3行5列的*号
-
用
*
号输出一个5行的等腰三角形 ,如下图
*
***
*****
*******
*********
复制代码
var r = 5
for (var i = 1; i <= r; i++) {
var str = '';
// 拼接空格,空格的数量为 r-i
for (var j = 0; j < r - i; j++) {
str += ' ';
}
// 拼接*号,数量为 2 * i - 1
for (var j = 0; j < 2 * i - 1; j++) {
str += '*';
}
console.log(str);
}
复制代码
- 求1到100之间所有的素数之和
var sum = 0;
for (var i = 1; i <= 100; i++) {
var isFind = false;
for (var j = 2; j < i; j++) {
if (i % j === 0) {
isFind = true;
break;
}
}
if (!isFind && i > 1) {
sum += i;
}
}
console.log(sum);
复制代码
- 输出99乘法表
for (var i = 1; i <= 9; i++) {
var str = ''
for (var j = 1; j <= i; j++) {
str += `${j} × ${i} = ${i * j}\t`;
}
console.log(str);
}
复制代码
- 假如投资的年利率为5%,试求从1000块增长到5000块,需要花费多少年
/*
* 假如投资的年利率为5%,试求从1000块增长到5000块,需要花费多少年
*
* 1000 1000*1.05
* 1050 1050*1.05
*/
//定义一个变量,表示当前的钱数
var money = 1000;
//定义一个计数器
var count = 0;
//定义一个while循环来计算每年的钱数
while (money < 5000) {
money *= 1.05;
//使count自增
count++;
}
console.log(money);
console.log("一共需要" + count + "年");
复制代码
- 将猜拳游戏升级,记录系统和玩家的积分,获胜者加1分,平局者和输者不计分
可以参考以下效果:
游戏开始
=============================第1轮=====================
系统:0分,玩家:0分
你的出拳:剪刀
系统出拳:布
你赢了!
==============================第2轮==========================
系统:0分,玩家:1分
你的出拳:石头
系统出拳:布
你输了!
===============================游戏结束==========================
系统:1分,玩家:1分
复制代码
var count = 1,
pcScore = 0,
playerScore = 0;
console.log('游戏开始');
while (true) {
console.log(`=============第${count}轮===================`);
console.log(`系统:${pcScore}分,玩家:${playerScore}分`);
var fist = prompt("你的出拳(石头,剪刀,布)");
//没有出拳,直接退出游戏
if (fist === null) {
break;
}
if (fist == '石头' || fist == '剪刀' || fist == '布') {
// 得到系统出拳
var ran = Math.random();
if (ran < 0.3333) {
var pcFist = '石头';
} else if (ran < 0.6666) {
var pcFist = '剪刀';
} else {
var pcFist = '布';
}
console.log(`你的出拳:${fist}`);
console.log(`系统出拳:${pcFist}`);
//比较输赢
if (fist == '石头' && pcFist == '剪刀' || fist == '剪刀' && pcFist == '布' ||
fist == '布' && pcFist == '石头') {
console.log('你赢了');
playerScore++;
} else if (fist == pcFist) {
console.log('平局');
} else {
console.log('你输了');
pcScore++;
}
// 轮次增加
count++;
} else {
console.log('出拳无效,请重新出拳');
}
}
console.log('=======================游戏结束=======================');
console.log(`系统:${pcScore}分,玩家:${playerScore}分`);
复制代码
数组
- 下面代码输出什么
var arr = [3, 6, 23, 4];
arr[0] = 10;
arr["0"] = 5;
console.log(arr[0], arr["0"]);//5 5
复制代码
- 下面代码输出什么
var obj = {
'2':3,
'3':4,
'length':2,
'splice':Array.prototype.splice,
'push':Array.prototype.push
}
obj.push(1);
obj.push(2);
obj.push(3);
console.log(obj);
复制代码
答案如下图
- 将一个字符串数组的元素的顺序进行反转,使用四种方式实现。
提示:第i个和第length-i-1个进行交换。(用多种方法)
//方法一
//采用双指针
var arr = [1,2,3];
var myreverse = function(arr) {
var i = 0,
j = arr.length - 1,
newArr = arr.slice();
while (i < j) {
var temp = newArr[j];
newArr[j] = newArr[i];
newArr[i] = temp;
i++;
j--;
}
return newArr;
}
----------------------------------------------------------------------
// 方法二
使用数组自带方法//
arr = arr.reverse();
-------------------------------
// 方法三
// 从数组最后一项依次遍历到数组第一项,把遍历到的每一个值存入新数组
function myreverse(arr) {
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
return newArr;
}
// 方法四
// 把数组第i个元素和数组 length - i - 1 个元素交换
function myreverse(arr) {
var newArr = arr.slice();
for (var i = 0; i < newArr.length / 2; i++) {
var temp = newArr[i];
newArr[i] = newArr[newArr.length - i - 1];
newArr[newArr.length - i - 1] = temp;
}
return newArr;
}
复制代码
- 提示用户输入数组的长度,以及数组每一项的值,然后输出该数组
var len = +prompt("请输入数组的长度");
if (isNaN(len) || len < 0) {
console.log('输入有误,请重新输入');
} else {
var arr = [];
for (var i = 0; i < len; i++) {
var value = prompt(`请输入数组中第${i + 1}项的值`);
arr[i] = value;
}
console.log(arr);
}
复制代码
- 初始化一个数字数组,然后求该数组所有项之和
- 初始化一个数组,然后输出该数组中所有的奇数
- 初始化一个数组,然后输出该数组中所有的素数
- 让用户输入斐波拉契数列的长度,在控制台中打印该斐波拉契数列
var len = +prompt("请输入斐波拉契数列的长度");
if (isNaN(len) || len <= 0) {
console.log('输入有误');
} else {
var arr = [];
for (var i = 0; i < len; i++) {
if (i === 0 || i === 1) {
arr[i] = 1;
} else {
arr[i] = arr[i - 1] + arr[i - 2];
}
}
}
console.log(arr);
复制代码
- 定义一个用户数组,数组的每一项是一个用户对象,该用户对象包含账号和密码,随意初始化一些对象放入
数组中,然后提示用户输入账号和密码判断是否登录成功
var users = [
{ loginId: 'abc', loginPwd: '123' },
{ loginId: 'abcd', loginPwd: '1234' },
{ loginId: 'abbb', loginPwd: '1235' },
{ loginId: 'aaaa', loginPwd: '1236' },
]
var loginId = prompt('请输入账号');
var loginPwd = prompt('请输入密码');
var isFind = false;
for (var i = 0; i < users.length; i++) {
if (loginId === users[i].loginId && loginPwd === users[i].loginPwd) {
isFind = true;
break;
}
}
if (isFind) {
console.log('登录成功');
} else {
console.log('登录失败');
}
复制代码
- 初始化一个5*5的二维数组,数组中的每一项是一个数字,计算对角线之和
var arr = [
[11, 12, 13, 14, 15],
[21, 22, 23, 24, 25],
[31, 32, 33, 34, 35],
[41, 42, 43, 44, 45],
[51, 52, 53, 54, 55]
]
var sum = 0;
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
if (i === j || j === (arr[i].length - i - 1)) {
sum += arr[i][j];
}
}
}
console.log(sum);
复制代码
- 初始化一个数字数组(数字随意),对该数组进行升序排序,然后输出结果
var arr = [9, 8, 7, 22, 18, 4, 3, 2, 1];
bubbleSort(arr);
console.log(arr);
function bubbleSort(arr) {
var swap = false;
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 1; j < arr.length - i; j++) {
if (arr[j] < arr[j - 1]) {
var temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
swap = true;
}
}
if (!swap) {
break;
}
}
}
复制代码
- 有一个数组存放了一些数字,找出频率出现最高的数字
var arr = [ 3, 4, 5, 4, 4, 2, 5, 9, 2, 4, 5, 2, 6, 9];
var obj = {};
for (var i = 0; i < arr.length; i++) {
if(obj[arr[i]]) {
obj[arr[i]]++;
} else {
obj[arr[i]] = 1;
}
}
var record = {
prop:undefined,
frequency:undefined
};
for(var prop in obj) {
if(obj[prop] > record["frequency"] || !record["prop"]) {
record.prop = +prop;
record.frequency = obj[prop]
}
}
console.log(record);
复制代码
- 自定义一个对象myArray()模拟Array()对象,并声明push(),pop()和toString()方法
function myArray() {
this.length = arguments.length;
for (var i = 0; i < arguments.length; i++) {
this[i] = arguments[i];
}
this.push = function() {
for (var i = 0; i < arguments.length; i++) {
this[this.length] = arguments[i];
this.length++;
}
return this.length;
}
this.pop = function() {
var value = this[this.length - 1];
delete this[this.length - 1];
this.length--;
return value;
}
this.toString = function() {
var result = '';
for (var i = 0; i < this.length; i++) {
result += this[i];
if(i < this.length - 1) {
result += '*';
}
}
return result;
}
}
var arr = new myArray(11, 22, 33, 44, 55);
arr.push(12, 120, 220);
arr.pop();
console.log(arr);
console.log(arr.toString());
复制代码
函数
函数的定义
- 通用函数编写(新建一个Js文件,编写以下函数)
-
写一个函数,该函数用于判断某个数是不是奇数(函数名:isOdd)
-
写一个函数,该函数用于判断某个数是不是素数 isPrime
-
写一个函数,该函数用于对数组求和 sumOfArray
-
写一个函数,该函数用于得到数组中的最大值 maxOfArray
-
写一个函数,该函数用于得到数组中的最小值 minOfArray
-
写一个函数,该函数用于判断数组是否是稀疏数组 hasEmptyInArray
-
写一个函数,判断该年是否是闰年 isLeap
-
写一个函数,得到某年某月的天数 getDays
-
写一个函数,得到某个数字数组中出现最多的数字和出现的频率 getTopFreqInArray
/**
* 判断一个数是否是奇数
* @param {number}
* @return {Boolean}
*/
function isOdd(num) {
return num % 2 !== 0;
}
/**
* 判断一个数是否是素数
* @param {number} [
* @return {Boolean}
*/
function isPrime(num) {
if (num < 2)
return false;
for (var i = 2; i < num; i++) {
if (num % i === 0)
return false;
}
return true;
}
/**
* 对一个数组求和
* @param {array}
* @return {number}
*/
function sumOfArray(arr) {
var sum = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
/**
* 得到数组中的最大值
* @param {arr}
* @return {number}
*/
function maxOfArray(arr) {
if (arr.length === 0) {
return;
}
var max = arr[0]
for (var i = 1; i < arr.length; i++) {
max = arr[i] > max ? arr[i] : max;
}
return max;
}
/**
* 得到数组中的最小值
* @return {array}
* @return {number}
*/
function minOfArray(arr) {
if (arr.length === 0) {
return;
}
var min = arr[0];
for (var i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i]
}
}
return min;
}
/**
* 判断一个数组是否是稀疏数组
* @param {arr}
* @return {Boolean}
*/
function hasEmptyInArray(arr) {
for (var i = 0; i < arr.length; i++) {
if (!(i in arr)) {
return true;
}
}
return false;
}
/**
* 判断给定的年是否是闰年
* @param {*}
* @return {Boolean}
*/
function isLeap(year) {
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
}
/**
* 得到某年某月的天数
* @param {*} 年
* @param {*} 月
* @return {*} 天数
*/
function getDays(year, month) {
return new Date(year, month, 0).getDate();
}
/**
* 得到数组中出现次数最多的数字和频率
* @param {Array}
* @return {Object}
*/
function getTopFreqInArray(arr) {
var records = {}
for (var i = 0; i < arr.length; i++) {
if(records[arr[i]]) {
records[arr[i]]++;
} else {
records[arr[i]] = 1;
}
}
var result = {
number:undefined,
frequency:undefined
}
var result;
for(var prop in records) {
if(!result || records[prop] > result["frequency"]) {
result["number"] = +prop;
result["frequency"] = records[prop];
}
}
return result;
}
复制代码
- 函数的使用
- 利用上面某些函数,实现哥德巴赫猜想
任意个大于2的偶数都可以改写成2个质数之和,让用户
输入一个大于2的整数,输出其等于哪2个素数相加
function begin() {
var num = +prompt("请输入一个大于2的偶数");
if (isNaN(num) || isOdd(num) || num <= 2) {
console.log("输入有误");
return;
} else {
for (var i = 2; i < num - 1; i++) {
var j = num - i;
if (isPrime(i) && isPrime(j) && i <= j) {
console.log(`${num} = ${i} + ${j}`);
}
}
}
}
复制代码
- 让用户输入一个年份,输出该年每个月的天数
begin();
function begin() {
var year = +prompt("请输入1990年到2100年之间的一个年份")
if (isNaN(year) || year < 1990 || year > 2100) {
console.log('输入不合法');
} else {
for (var m = 1; m <= 12; m++) {
console.log(`${year}年${m}月:${getDays(year,m)}天`);
}
}
}
复制代码
函数表达式与this
- 下面的程序输出什么
function f1() {
var arr = [];
var a = 1;
for (var i = 1; i <= 3; i++) {
arr.push(function() {
return i * a++;
})
}
return arr;
}
f1().forEach(function(item) {
console.log(item()); // 4 8 12
})
复制代码
- 下面的代码输出什么
var number = 5;
var obj = {
number: 3,
fn1: (function () {
var number;
this.name *= 2;
number = number * 2;
number = 3;
return function () {
var num = this.number;
this.number *= 2;
console.log(num); //5 3
number *= 3;
console.log(number); //9 27
}
})()
}
var fn1 = obj.fn1;
fn1.call(null);
obj.fn1();
console.log(number); //10
复制代码
- 写一个函数,为数组排序,要考虑到这个数组的所有的可能 sort
function sort(arr, callback) {
if (!callback) {
callback = function(a, b) {
if (a > b) {
return 1
} else if (a === b) {
return 0
} else {
return -1;
}
}
}
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - 1 - i; j++) {
if (callback(arr[j], arr[j + 1]) > 0) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
复制代码
- 写一个函数,按照指定的条件对数组进行筛选 filter
function filter(arr, callback) {
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (callback(arr[i], i)) {
newArr.push(arr[i]);
}
}
return newArr;
}
复制代码
- 写一个函数,按照指定的条件,得到数组中第一个满足条件的元素 find
function find(arr, callback) {
for (var i = 0; i < arr.length; i++) {
if (callback(arr[i], i)) {
return arr[i];
}
}
return;
}
复制代码
- 写一个函数,按照指定的条件,得到数组中满足条件的元素的数量 count
function count(arr, callback) {
var num = 0;
for (var i = 0; i < arr.length; i++) {
if (callback(arr[i], i)) {
num++;
}
}
return num;
}
复制代码
构造函数
- 英雄打怪兽小游戏
英雄和怪兽都具有攻击力,防御力,生命值,暴击几率(暴击时伤害翻倍)
攻击伤害 = 攻击力 – 防御力
伤害最少为1
创建一个英雄和一个怪兽,让他们互相攻击,直到一方死亡,输出整个攻击过程
/**
* 游戏角色的构造函数
* @param {*} name 角色名
* @param {*} attack 攻击力
* @param {*} defence 防御力
* @param {*} hp 生命值
* @param {*} critRate 暴击率(0 - 100)
*/
function Charactor(name, attack, defence, hp, critRate) {
this.name = name;
this.attack = attack;
this.defence = defence;
this.hp = hp;
this.critRate = critRate;
/**
* 打印信息
*/
this.print = function() {
console.log(`${this.name}\t生命值:${this.hp}\t攻击力:${this.attack}\t防御力:${this.defence}\t暴击率:${this.critRate}%`);
}
/**
* 攻击
* @param {*} ctor 被攻击角色
*/
this.hit = function(ctor) {
var damage = this.attack - ctor.defence;
// 判断是否有暴击
var isCrit = false;
var ran = Math.random();
if (ran <= this.critRate / 100) {
damage *= 2;
isCrit = true;
}
// 伤害至少为1
if (damage < 1) {
damage = 1;
}
ctor.hp -= damage;
// 生命值至少为0
if (ctor.hp < 0) {
ctor.hp = 0;
}
console.log(`${isCrit?'暴击!':''}【${this.name}】攻击【${ctor.name}】,造成${damage}点伤害,对方当前血量值为${ctor.hp}`);
// 返回对方是否死亡
return ctor.hp === 0;
}
}
var hero = new Charactor("英雄", 100, 20, 500, 30);
var monster = new Charactor("怪兽", 120, 40, 400, 5);
hero.print();
console.log('vs');
monster.print();
console.log('-------------游戏开始----------------------');
while (true) {
if (hero.hit(monster)) {
break;
}
if (monster.hit(hero)) {
break;
}
}
console.log('========================================');
hero.print();
monster.print();
console.log('----------------游戏结束-------------------');
复制代码
递归
- 汉诺塔问题
function hannuo(n1, n2, n3, n) {
if (n === 1) {
console.log(`${n1}--->${n3}`);
} else {
hannuo(n1, n3, n2, n - 1);
console.log(`${n1}--->${n3}`);
hannuo(n2, n1, n3, n - 1);
}
}
hannuo('A', 'B', 'C', 4);
复制代码
执行上下文和作用域链
- 画出下面代码作用域链
知识点提示
VO中包含一个额外的属性,该属性指向创建该VO的函数本身
每个函数在创建时会有一个隐藏属性[[scope]]
,它指向创建该函数时的AO
当访问一个变量时,会先查找自身VO中是否存在,如果不存在则依次查找[[scope]]
属性
- 画图理解题
1.画出下面代码作用域链
var g = 0;
function A() {
var a = 1;
function B() {
var b = 2;
var C = function() {
var c = 3;
console.log(c, b, a, g);
}
C();
}
B();
}
A();
复制代码
2.画出下面代码作用域链,有闭包形成
function A() {
var count = 0;
return function() {
count++;
console.log(count);
}
}
var test = A();
test();
test();
test();
console.log(count);
复制代码
3.利用闭包让定时器打印不同的值,画图理解
for (var i = 0; i < 3; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
},1000);
})(i)
}
复制代码
- 面试题(打印输出结果,画出原型链图)
var foo = { n: 1 };
(function(foo) {
console.log(foo.n); //1
foo.n = 3;
var foo = { n: 2 };
console.log(foo.n); //2
})(foo);
console.log(foo.n); //3
复制代码
let food = "rice";
let eat = function() {
console.log(`eat ${food}`); //eat rice
};
(function() {
let food = "noodle";
eat();
})();
复制代码
var food = "rice";
(function () {
var food = "noodle";
var eat = function () {
console.log(`eat ${food}`);
};
eat(); //eat noodle
})();
复制代码
function A() {
for (i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i); //打印10个10
}, 1000)
}
}
A();
console.log(i); //10
复制代码
作用域链精华练习题
console.log(a) //undefined
var a = 12
function fn() {
console.log(a) //undefined
var a = 13
}
fn()
console.log(a) //12
复制代码
console.log(a) //undefined
var a = 12
function fn() {
console.log(a) //12
a = 13
}
fn()
console.log(a) //13
复制代码
console.log(a) //报错
let a = 12
function fn() {
console.log(a)
let a = 13
}
fn()
console.log(a)
复制代码
console.log(a) //报错
a = 12
function fn() {
console.log(a)
let a = 13
}
fn()
console.log(a)
复制代码
var foo = 1
function bar() {
if(!foo){
var foo = 10
}
console.log(foo) //10
}
bar();
复制代码
var foo = 1
function bar() {
if(!foo){
foo = 10
}
console.log(foo) //1
}
bar()
复制代码
var n=0
function a() {
var n = 10
function b() {
n++
console.log(n) //11
}
b()
return b
}
var c=a()
c() //12
console.log(n); //0
复制代码
var a=10
var b=11
var c=12
function test(a){
a = 1
var b = 2
c = 3
}
test(100)
console.log(a) //10
console.log(b) //11
console.log(c) //3
复制代码
if(!('a' in window)){
var a = 10
}
console.log(a) //undefined
复制代码
var a = 4
function b(x, y, a) {
console.log(a) //3
arguments[2] = 10
console.log(a) //10
}
a = b(1,2,3);
console.log(a) //undefined
复制代码
var a = 9
function fn() {
a = 0
return function(b){
return b+a++
}
}
var f=fn()
console.log(f(5)) //5
console.log(fn()(5))//5
console.log(f(5)) //6
console.log(a) //2
复制代码
var ary = [1,2,3,4]
function fn(ary){
ary[0] = 0
ary = [0]
ary[0] = 100
return ary
}
var res = fn(ary)
console.log(ary) //[0,2,3,4]
console.log(res) //[100]
复制代码
function fn(i){
return function(n){
console.log(n + (i++));
}
}
var f = fn(10)
f(20) //30
fn(20)(40) //60
fn(30)(50) //80
f(30) //41
复制代码
var num = 10;
var obj = {num: 20};
obj.fn = (function(num){
this.num = num * 3
num++
return function (n) {
this.num += n;
num++;
console.log(num);
}
})(obj.num);
var fn = obj.fn
fn(5) //22
obj.fn(10) //23
console.log(num, obj.num) //65,30
复制代码
var fullName = 'language'
var obj = {
fullName: 'javascript',
prop: {
getFullName: function() {
return this.fullName
}
}
}
console.log(obj.prop.getFullName()) //undefined
var test = obj.prop.getFullName
console.log(test()) //language
复制代码
var name = 'window'
var Tom = {
name: "tom",
show: function() {
console.log(this.name)
},
wait: function() {
var fun = this.show
fun()
}
}
Tom.wait() //window
复制代码
String 对象
- 实现函数,查找子串出现的次数,返回字符串str中出现substring的次数
传入:”abcabcabc”, “abc”; 返回:3
function searchSub(string, sub) {
var i = 0;
var len = sub.length;
var count = 0;
while ((i = string.indexOf(sub, i)) !== -1) {
i += len;
count++;
}
return count;
}
复制代码
- 反转一个三位整数
// 方法一:用数组的reverse方法
function reverseNum(num) {
if (isNaN(num) || Math.abs(num) < 100 || Math.abs(num) > 999) {
return;
}
var sign = Math.sign(num);
var numAbs = Math.abs(num);
return +(numAbs.toString().split('').reverse().join('')) * sign;
}
// 方法二:
function reverseNum(num) {
if (isNaN(num) || Math.abs(num) < 100 || Math.abs(num) > 999) {
return;
}
var sign = Math.sign(num);
var numAbs = Math.abs(num);
var total = 0;
while(numAbs) {
total = total * 10 + numAbs % 10;
numAbs = Math.floor(numAbs / 10);
}
return total * sign;
}
console.log(reverseNum(+prompt()));
复制代码
- 已知一个字符串对象中,英语单词用各种非字母字符分割,统计
单词的个数
传入:'Yes,she**is%%my@love.'
var str = 'Yes,she**is%%my@love.';
console.log(total(str));
//方法一,把连续非字母字符替换成一个空格字符,去掉首尾空格,然后用空格分隔成数组,
//返回数组的长度
function total(str) {
var len = str.length;
str = str.replace(/[^a-zA-Z]+/g, ' ').trim();
return str.split(' ').length;
}
// 方法二
function total(str) {
var len = str.length;
var reg = /[a-zA-Z]/;
var count = 0;
var newArr = [];
var firstIndex = 0;
for (var i = 0; i < len; i++) {
if (reg.test(str[i])) {
} else {
count++;
newArr.push(str.substring(firstIndex, i));
firstIndex = i + 1;
while (!reg.test(str[firstIndex]) && i < len) {
i++;
firstIndex++;
}
}
}
return newArr.length;
}
复制代码
- 找出字符串中出现次数最多的字母
将该字母和字母出现的次数拼接成一个新字符串,返回新字符串
传入:'WelcomeToQianfeng'
;
返回:'e3'
; (要求编写成函数)
var str = 'WelcomeToHeiMa';
console.log(count(str));
//方法一: 先转数组按字符编码排序,在统计 键------>数量 值------>字符
function count(str) {
var index = 0;
var result = [];
var arr = str.split('').sort();
for (var i = 0; i < arr.length; i++) {
if(result.indexOf(arr[i]) === -1) {
index = 0;
result[index] = arr[i];
} else {
result[++index] = arr[i];
}
}
return result.length + result[result.length - 1];
}
//方法二:统计 键------>数量 值------>字符 依次查找每个字符出现的次数,并存入数组相应的位置
function count(str) {
var arr = [];
for (var i = 0; i < str.length; i++) {
var fread = 0;
var j = 0;
while ((fread = str.indexOf(str.charAt(i), fread)) !== -1) {
fread++;
j++;
}
arr[j] = str.charAt(i);
}
return arr.length - 1 + arr[arr.length - 1];
}
复制代码
Array 对象
var arr = [1,2,3,4,5,6,-1,-2,-3,-4,-5,-6];
去掉数组中的负数,然后对每一项平方,然后在对没一项翻倍,然后求和
不许使用循环
var arr = [1, 2, 3, 4, 5, 6, -1, -2, -3, -4, -5, -6];
var sum = arr.filter(function(item) {
return item >= 0;
}).map(function(item) {
return item * item * 2;
}).reduce(function(s, item) {
return s + item;
}, 0);
console.log(sum);
复制代码
原始类型包装器
- 找到某个字符串中出现最多的字符,打印字符和他出现的次数
// 巧妙办法,先排序,每遍历一个新字符就从起始位置开始存入数组,非新字符就依次往后存放
// 最后没有被覆盖的字符就是出现次数最多的字符
function count(str) {
var temp = str.split('').sort();
var result = [];
for (var i = 0; i < temp.length; i++) {
if (result.includes(temp[i])) {
result[++count] = temp[i];
} else {
var count = 0;
result[count] = temp[i];
}
}
console.log(result.length + result[result.length - 1]);
}
复制代码
- 将一个字符串中单词之间的空格去掉,然后把每个单词首字母大写
var str = 'my name is liu\tchao\nhow are you';
console.log(bigCamel(str));
console.log(bigCamel2(str));
// 第一种方法
function bigCamel(str) {
var temp = str.split(/[\n\s\t]+/g);
var res = temp.map(function(item) {
return item[0].toUpperCase() + item.substring(1);
});
return res.join('');
}
// 第二种方法
function bigCamel2(str) {
var empties = ' \n\r\t';
var res = '';
for (var i = 0; i < str.length; i++) {
if (!empties.includes(str[i])) {
if (!empties.includes(str[i - 1]) && i !== 0) {
res += str[i];
} else {
res += str[i].toUpperCase();
}
}
}
return res;
}
复制代码
- 书写一个函数,产生指定长度的随机字符串,字符串中只能包含大小写字母,数字
console.log(getRandomString(10))
function getRandomString(len) {
var template = '';
for (var i = 97; i < 97 + 26; i++) {
template += String.fromCharCode(i);
}
for (i = 65; i < 65 + 26; i++) {
template += String.fromCharCode(i);
}
for (i = 48; i < 48 + 10; i++) {
template += String.fromCharCode(i);
}
var res = '';
for (i = 0; i < len; i++) {
var index = MyFunctions.getRandom(0, template.length - 1);
res += template[index];
}
return res;
}
复制代码
- 将字符串按照字符编码的顺序重新升序排序
var str = 'adjfkgjiedkj';
var newStr = str.split('').sort().join('');
console.log(newStr);
复制代码
- 从一个标准的身份证号中取出用户的出生年月日和性别,保存在对象中
var pid = '420114199609210533';
console.log(getInfoFromPID(pid));
function getInfoFromPID(pid) {
return {
birthdayYear: +pid.substr(6, 4),
birthdayMonth: +pid.substr(10, 2),
birthdayDay: +pid.substr(12, 2),
gender: pid[pid.length - 2] % 2 === 0 ? '女' : '男'
}
}
复制代码
Date 对象
- 获取每一个月的天数
方法一:
function getDays(year, month) {
return new Date(year, month, 0).getDate();
}
复制代码
方法二:
function getDays(year, month) {
var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
// 判断是否是闰年
var isLeap = year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
if (month === 2) {
return isLeap ? days[month - 1] + 1 : days[month - 1];
}
return days[month - 1];
}
复制代码
-
获取指定格式的日期
-
根据出生日期计算年纪
function getAge(year, month, date) {
var now = new Date();
var nowYear = now.getFullYear();
var age = nowYear - year;
month -= 1;
var isLeap = nowYear % 4 === 0 && nowYear % 100 !== 0 || nowYear % 400 === 0;
if (month === 1 && date === 29 && !isLeap) {
month = 28;
}
var thisYearBirthday = new Date(nowYear, month, date);
if (now < thisYearBirthday) {
age--;
}
return age;
}
复制代码
- 根据出生日期计算距离生日还有多少天
function getbirthday(month, date) {
var now = new Date();
var nowYear = now.getFullYear();
var thisYearBirthday = new Date(nowYear, month - 1, date);
if (now > thisYearBirthday) {
// 今年的生日过了,就算距离明年的生日
thisYearBirthday.setFullYear(nowYear + 1);
}
return Math.ceil((thisYearBirthday.getTime() - now.getTime()) / 1000 / 3600 / 24);
}
复制代码
- 输出给定的一个月中每一天星期几
function getdays(year, month) {
var dateObj = new Date(year, month - 1);
var week = ['日',
'一', '二', '三', '四', '五', '六'
];
// 1.求出给定的月份的天数
var days = new Date(year, month, 0).getDate();
// 2.循环打印每天的星期
for (var i = 0; i < days; i++) {
dateObj.setDate(i + 1);
console.log(`${year}年${month}月${i+1}日:星期${week[dateObj.getDay()]}`)
}
}
复制代码
正则表达式
- 书写一个正则表达式,去匹配一个字符串,得到匹配的数量和匹配的结构
var str = '123sldfjf43435djfd124dfkdj888jfdkjf136';
var reg = /\d{3}/g;
var res = '',
result = '',
count = 0;
while (res = reg.exec(str)) {
result += (res[0] + '\n');
count++;
}
console.log(`匹配了${count}次,匹配的字符串是:\n${result}`);
复制代码
- 得到一个字符串中的中文的数量
var str = '军抵抗akjfdkfjjf酒店服务大风降温';
var count = 0,
reg = /[\u4e00-\u9fa5]/g
while (reg.exec(str)) {
count++;
}
console.log(count);
复制代码
- 过滤敏感词,有一个敏感词组,需要将字符串中出现的敏感词替换为
****
var senWords = ['共产党', '暴力', '卢本伟', '贸易战'];
var str = '的肌肤共产党ajdf暴力暴力暴力dkfj卢本伟jjfd贸易战ggdfj文件';
console.log(removeSensitiveWord(str, '****'));
//动态生成正则表达式
// ('共产党'|'暴力'|'卢本伟'|'贸易战')+
function removeSensitiveWord(str, rep) {
var reg = new RegExp(`(${senWords.join('|')})+`, 'g');
return str.replace(reg, function ($) {
return rep;
})
}
复制代码
- 判断密码强度
要求密码中必须出现小写字母,大写字母,数字,特殊字符(!@#_,.)
,6到12位
/^(?=.*[a-z]+)(?=.*[A-Z]+)(?=.*[0-9]+)(?=.*[!@#_,.]+).{6,12}$/
复制代码
- 判断密码强度
密码长度必须是6到12位
出现小写字母,大写字母,数字,特殊字符`(!@#_,.)` 强
出现小写字母,大写字母,数字 中
出现小写字母,大写字母 轻
其他 不满足要求
复制代码
var str = prompt('请输入密码');
if (/^(?=.*[a-z]+)(?=.*[A-Z]+)(?=.*[0-9]+)(?=.*[!@#_,.]+).{6,12}$/.test(str)) {
alert('密码强度强');
} else if (/^(?=.*[a-z]+)(?=.*[A-Z]+)(?=.*[0-9]+).{6,12}$/.test(str)) {
alert('密码强度中');
} else if (/^(?=.*[a-z]+)(?=.*[A-Z]+).{6,12}$/.test(str)) {
alert('密码强度轻');
} else {
alert('不满足要求');
}
复制代码
Es6
箭头函数
- 下面的this指向
var obj = {
name: 'lily',
fun: function() {
return (() => this.name)()
},
fn: () => this.name
};
name = 'lucy';
console.log(obj.fn());//lucy
console.log(obj.fun());//lily
箭头函数一般用作回调函数
复制代码
数组扩展
- 用filter给数组去重
var x = ['a', 'a', 'b', 'b', 'c', 'b', 'a'];
var y = x.filter(function(item, index) {
if (x.indexOf(item) == index) {
return item;
}
});
console.log(y)
复制代码
- 用reduce 给数组去重
//方法一
var x = ['a', 'a', 'b', 'b', 'c', 'b', 'a'];
var y = x.reduce(function(arr, item, index) {
if (x.indexOf(item) == index) {
arr.push(item)
}
return arr;
}, []);
console.log(y);
//方法二
var y = x.reduce(function(arr, a, b) {
if (!arr.includes(a)) {
arr.push(a);
}
return arr;
}, [])
复制代码
- 用reduece 统计数组中各项的个数
var x = ['a', 'a', 'b', 'b', 'c', 'b', 'a'];
var y = x.reduce(function(obj, item) {
if (item in obj) {
obj[item]++;
} else {
obj[item] = 1;
}
return obj
}, {});
console.log(y);
复制代码
- 用reduce 给数组扁平化