一、JS中的数据类型检测
- typeof [val]:用来检测数据类型的运算符
- instanceof :用来检测当前实例是否率属于某个类
- constructor : 基于构造函数检测数据类型(也是基于类的方式)
- Object.prototype.toString.call() :检测数据类型最好的办法
typeof的特点
/*
* 基于 typeof 检测出来的结果
* 1. 首先是一个字符串
* 2. 字符串中包含对应的类型
* 局限性
* 1. typeof null => "object" 但是 null 并不是对象
* 2. 基于 typeof 无法细分出当前值是普通对象还是数组对象等,因为只要是对象数据类型,返回的结果都是"object"
*/
console.log(typeof 1);
let a = NaN;
console.log(typeof a); // 'number'
// console.log(typeof typeof typeof []);
// typeof [] => "object"
// typeof "object" => "string"
// 因为 typeof 检测的结果都是字符串,所以只要两个及以上同时检测,最后结果必然是 "string"
二、JS中的操作语句:判断、循环
判断
条件成立做什么?不成立做什么?
- if / else if / else
- 三元运算符
- switch case
- if / else
if(条件) {
条件成立执行
}else if (条件2) {
条件2成立执行
}
// A && B:A和B都成立才为 TRUE
// A || B:A或者B只有一个成立就为 TRUE
// 它们是有返回值的:
// || 如果第一个时 true,就返回第一个,如果第一个 false 就返回第二个
// && 如果第一个是 false,就返回第一个,如果第一个 true 就返回第二个
// 条件可以多样性:等于、大于、小于的比较/一个值或者取反等 => 最后都是要计算出是 TRUE 还是 FALSE
...
else{
以上条件都不成立
}
- 三元运算符:简单 IF / ELSE 的特殊处理方式
条件?条件成立处理的事情:不成立处理的事情;
1.如果处理的事情比较多,我们用括号包起来,每一件事情用逗号分隔
2.如果不需要处理事情,可以使用 null / undefined 占位
let a = 10;
// if / else
if (a > 0) {
if (a < 10) {
a++;
} else {
a--;
}
} else {
if (a > -10) {
a += 2;
}
}
// 改写成三元运算符
a > 0 ? (a < 10 ? a++ : a--) : (a > -10 ? a += 2 : null);
switch case:一个变量在不同值情况下的不同操作
1.每一种 case 情况结束后最好都加上 break
2.default等价于 else,以上都不成立干的事情
3.每一种 case 情况的比较用的都是 === “绝对相等”== VS ===
==:相等(如果左右两边数据值类型不同,是默认先转换为相同的类型,然后比较)
‘5’==5 // TRUE===:绝对相等(如果类型不一样,肯定不相等,不会默认转换数据类型)
‘5’===5 // FALSE
项目中为了保证业务的严谨,推荐使用 ===
let a = '5';
switch (a) {
case 1:
console.log('呵呵');
break;
case 5: // 此处 '5' case 5 => FALSE
console.log('哈哈');
break;
default:
console.log('嘻嘻');
}
// 如果不加 break,当前条件成立执行完成后,后面条件不论是否成立都要执行,直到遇到 break 为止(不加 break 可以实现变量在某些值的情况下做相同的事情 => 编程开发人员要具备探索尝试之心)
循环
重复做某些事情就是循环
- for 循环
- for in 循环
- for of 循环(ES6新增)
- while 循环
- do while 循环
/*
* 1.创建循环初始值
* 2.设置(验证)循环执行的条件
* 3.条件成立执行循环体中的内容
* 4.当前循环结束执行步长累计操作
*/
for (var i = 0; i < 5; i++) {
// console.log(i); // 0 1 2 3 4
}
console.log(i); // 5
for (var i = 10; i > 4; i -= 2) {
if (i < 7) {
i++;
} else {
i--
}
}
console.log(i);
// 循环体中的两个关键词
// continue:结束当前这轮循环(continue 后面的代码不再执行),继续执行下一轮循环
// break: 强制结束整个循环(break 后面代码也不再执行),而且整个循环啥也不干直接结束
for (var i = 0; i < 10; i++) {
if (i >= 2) {
i += 2;
continue;
}
if (i >= 6) {
i--;
break;
}
i++;
console.log(i);
}
console.log(i);
// while 和 do while
while (/* 循环条件*/) {
// 内容
}
do {
// 先执行 后判断
} while (/* 循环条件*/) {
// 内容
}
for in循环
for in 循环是专门用来遍历对象的,可以把对象里面的属性一个一个的遍历出来。 注意:for in 只能遍历对象的可枚举属性。一般浏览器默认添加的都是不可枚举的属性。例如proto****
var obj = {
name: '珠峰',
age: 10
};
for (var k in obj) {
// k 代表每次遍历时的属性名
console.log('k ', k);
console.log('obj[k]', obj[k]);
}
三、fucntion
函数就是一个方法,或者一个功能体,函数就是把实现某个功能的代码放到一起进行封装,以后想要操作实现这个功能,只需要把函数执行即可,“封装”。 封装:减少页面中的冗余代码,提高代码的重复使用率(低耦合高内聚)
创建函数:形参,返回值
执行函数:实参
argrments:实参集合
1. 创建函数
// es5 老方式
function[函数名]([形参变量1],...){
// 函数体:基于 js 完成需要实现的功能
return[处理后的结果];
}
[函数名]([实参1],...)
2. 形参的细节
创建函数的时候,我们设置了形参变量。但如果执行的时候并没有给传递对应的实参,那么形参变量默认的值是undefined
null == undefined // true
3. return细节问题
函数执行时,函数体内部创建的变量 ,我们是无法获取和操作的。如果想要获取内部的信息,我们需要基于return 返回值机制,把信息返回才可以
document.body.onclick = function () {
// 匿名函数之函数表达式,把一个匿名函数本身作为值赋值给其他东西,这种函数一般不是手动触发执行,而且靠其他程序驱动触发执行(例如:触发某个事件的时候把它执行等)
}
// 自执行函数
(fucntion () {
// n = 100;
})(100)
// 创建完一个匿名函数,紧接着就把当前加小括号执行
// 自执行函数:前面加的()或者!、-、~、+只有一个目的,让语法符合而已
// 自执行函数本身不进行变量提升(没名字)
(function(n){})(10);
~function(n){}(10);
-function(n){}(10);
!function(n){}(10);
+function(n){}(10);
四、对象的操作
let obj = new Object() // new 一个对象出来
如何遍历对象?
let obja = {
name: 'aa',
age: 16,
hobby: '唱跳 rap 篮球'
}
for (let obj in obja) {
console.log(obj);
}
Object.getOwnPropertyNames() // 可以遍历不可枚举属性
object.keys()
// 删除属性:delete obj.marry;
// 当一个对象的属性名为变量或者数字的时候,对象就不能通过对象点属性名获取它的值;需要通过 obj[属性名] 获取
如果想操作对象?
{
value: 123; // value 是属性的属性值,默认为 undefined
writable: false; // 表示属性值是否可改变(即是否可写),默认为 true
enumerable: true; // 表示该属性是否可遍历 默认为 true
configurable: false; // 表示可配置性,默认为 true 如果是 flase 表示无法删除该属性
get: undefined; // 一个函数,代表 getter
set: undefined; // 一个函数,代表 setter
Object.getOwnPropertyDesctiptor(obj, 'p') // 获取属性描述对象
Object.getOwnPropertyNames() // 返回一个数组,成员是参数对象自身的全部属性名,不管该属性是否可遍历
// 注意:一旦定义了取值函数 get 或 set 就不能设置 writable 或者同时定义 vlaue 属性,否则报错
Object.preventExtensions(obj) // 使对象无法添加新属性
Object.isExtensible(obj) // 检查一个对象是否用了 Object.preventExensions 方法
Object.seal(obj) // 让一个对象不能添加新属性且不能删除旧属性
Object.isSealed(obj) // 检查一个对象有没有用 Object.seal 方法
Object.freeze(obj) // 使一个对象不能添加不能删除不能改变属性的值,相当于常量
Object.isFrozen(obj) // 检查一个对象有没有用 Object.freeze 方法
obj.hasOwnProperty('p') // 检查对象里是否包含该属性
}