【JavaScript】JS的坚实基础

前言 ? 考虑到在后面的开发中,需要大量的使用js语言去进行开发,所以准备重新规整一下javascript的知识点,专门开了一个js的专栏,用来复习一下js语言。万事开头难,要是后面写的有问题的,欢迎大家在下方无情抽脸!!!
【JavaScript】JS的坚实基础
文章图片

数据类型 在JavaScript中大体存在2大类数据类型,值类型引用类型;

  • 值类型:StringNumberBooleanNullUndefined以及Symbol
    值类型是按值存储,数据存储在内存栈中,
    NumberStringBoolean,Symbol都对应了一个包装对象,例如:new Number(5)
    这也是能用原始数据类型调用方法的原理:
    【【JavaScript】JS的坚实基础】eg:('happy').toString(),'happy'是一个基本数据类型,本身没有toString的这个方法,所以通过调用ToObject [spec]将值转换为对象,然后去它的包装对象new String('happy')中调用,调用完成后包装对象就会消失,下次需要就会重新创建。
  • 引用类型: ObjectArrayFunction
    引用类型按引用存储的,存储的不是值,而是一个地址,数据存储在内存堆中
数据类型检测常用方法
  • typeof 主要用于原始类型的检测
typeof 'seymoe'// 'string' typeof true// 'boolean' typeof 10// 'number' typeof Symbol()// 'symbol' typeof null// 'object' 无法判定是否为 null typeof undefined// 'undefined' typeof {}// 'object' typeof []// 'object' typeof(() => {})// 'function'

  • instanceof 主要用于检测自定义对象
// 测试构造函数的prototype是否在被检测对象obj的原型链上面 // obj instanceof 构造函数的prototype [] instanceof Array// true ({}) instanceof Object// true (()=>{}) instanceof Function// true

  • Object.prototype.toString.call数据类型判断的终极方法
    该方法本质就是依托Object.prototype.toString()方法得到对象内部属性 [[Class]]
    传入原始类型却能够判定出结果是因为对值进行了包装
    nullundefined 能够输出结果是内部实现有做处理
// Object.prototype.toString.call(obj) Object.prototype.toString.call({})// '[object Object]' Object.prototype.toString.call([])// '[object Array]' Object.prototype.toString.call(() => {})// '[object Function]' Object.prototype.toString.call('seymoe')// '[object String]' Object.prototype.toString.call(1)// '[object Number]' Object.prototype.toString.call(true)// '[object Boolean]' Object.prototype.toString.call(Symbol())// '[object Symbol]' Object.prototype.toString.call(null)// '[object Null]' Object.prototype.toString.call(undefined)// '[object Undefined]' Object.prototype.toString.call(new Date())// '[object Date]' Object.prototype.toString.call(new Math())// '[object Math]' Object.prototype.toString.call(new Set())// '[object Set]' Object.prototype.toString.call(new WeakSet())// '[object WeakSet]' Object.prototype.toString.call(new Map())// '[object Map]' Object.prototype.toString.call(new WeakMap())// '[object WeakMap]'

var、let和const 最开始使用javascript的时候var耍的那叫一个炉火纯青,等es6出来后提供的letconst关键字一开始觉得没有var好用,等实际用过后才发现真香!!!(???)?基本现在var已经给淘汰了。
  • var:全局作用域(函数内),声明存在变量提升,好用是好用,难受也难受!
    执行javascript代码时会分为俩个阶段,预编译阶段运行时阶段
    其中在预编译阶段时候会进行变量声明提升,意思就是会将var定义的变量声明放到代码顶部,变量赋值则是在代码运行时阶段进行,可以通过下面的实例来理解一下JS执行时的变量提升。
    console.log(a); var a = 0; // 等价于 var a = undefined; console.log(a); a = 0;

    当然,除了变量提升外,函数提升也是一样的,大家感兴趣的可以自己试一下。
    function fun() {}//这种声明写法会导致函数提升,所以不论声明在什么位置,都可以调用它,且它本身不会执行var foo = function(){}//这种写法会导致变量提升,但是不会导致函数提升,这时候就必须先声明再调用

  • let:块级作用域,可以看成{}形成一个块级作用域
    首先let声明变量不会进行变量提升,也就是说如果想要使用let声明的变量,必须在使用之前声明该变量;
    在for循环中可以通过let来给每一次循环时的变量分配各自作用域,从而互不影响。
    // 不存在变量提升 console.log(a); // a is not defined. let a = 1; // 块级作用域 let b = 1; { console.log(b) // 1 作用域内可以访问作用域外申明的变量 let c = 1; } console.log(c) // c is not defined. 作用域外访问不到作用域内申明的变量

  • const:块级作用域
    let关键字一样会形成块级作用域,但是const通常用来声明一个常量!
    对于栈存储类型数据来说,通过const申明赋值之后便不可更改;
    对于堆存储类型数据来说,通过const申明赋值之后堆引用地址不可更改,但是可以更改堆地址对应的数据(比如对象的属性,数组的选项等!)
字符串API
str.split('-')//按-分割字符串返回一个数组 str.substr(startIndex , count)//返回截取的新字符串 str.substring(startIndex , endIndex)//返回新字符串(包括startIndex不包括endIndex) str.slice(startIndex , endIndex)//返回新字符串(包括startIndex不包括endIndex) str.repalce(旧字符串 , 新字符串)//替换字符串 str.toLowerCase()//转小写 str.toUpperCase()//转大写 str.trim()//去除两端空格 str.charAt ( index )//返回index位置的字符 str.concat ( str1 , str2 , ...)//返回拼接后的新字符串 str.indexOf (str1 , startIndex)//返回str1的位置索引,没有返回-1 str.lastIndexOf ( str1 )//从后向前找返回str1的位置索引,没有返回-1

数字API
Math.abs(x)//返回 x 的绝对值。 Math.ceil(x)//返回 x,向上舍入为最接近的整数。 Math.floor(x)//返回 x,向下舍入为最接近的整数。 Math.max(x, y, z, ..., n)//返回值最大的数字。 Math.min(x, y, z, ..., n)//返回值最小的数字。 Math.pow(x, y)//返回 x 的 y 次幂值。 Math.random()//返回 0 到 1 之间的随机数。 Math.round(x)//将 x 舍入为最接近的整数。 Math.trunc(x)//返回数字 (x) 的整数部分。

数组API
// splice会改变原始数组 array.splice(startIndex , deleteCount , item1,item2, ...)// 一般用于删除元素(也可替换(插入)元素)// slice返回一个新数组 array.slice(?startIndex , ?endIndex)// 截取的数组值放入一个新的数组中(不包括endIndex位置的元素)// includes:ES7中的,判断该数组中是否包含指定的值 array.includes(elem,[startIndex]) // 和indexOf的区别是includes可以发现NaN,而indexOf不能 [NaN].includes(NaN) // true [NaN].indexOf(NaN) // -1array.concat(array1 , array2 , ...)// 组合返回新数组 array.push( item )// 插入数组最后位置,返回数组新的长度 array.pop()// 删除数组最后一个元素,返回删除的这个元素值 array.shift()// 删除数组的第一个元素,返回删除的这个元素值 array.unshift( item )// 在数组第一个元素之前插入新元素,返回新数组的长度 array.join('-')// 以-将数组每一项拼成一个字符串,返回拼凑好的字符串 // array.join()array.toString() array.reverse()// 反转数组并返回 array.sort(function(a, b) { return a-b; })// 排序(升序)// 循环遍历 array.forEach(function(value){}) array.forEach(function(value,index,newArray){})// Map遍历数组的每一项,把执行后的结果全部插入一个新的数组中并返回 array.map(function(value){ return value*2; })// Filter返回符合条件的值组成的新数组 array.filter(function(value){ return value>3; })// Every返回true/false(只有数组每一项都符合条件才会返回true)【确定了结果就会停止遍历】 array.every(function(value){ return value>0; })// Some返回true/false(只要数组中有一项满足条件就会返回true)【确定了结果就会停止遍历】 array.some(function(value){ return value>0; })// indexOf()返回查找元素从前往后的第一个元素位置索引 var index = ['tang','fu','qiang','fu'].indexOf('fu'); // index为1; // lastIndexOf()返回查找元素从后往前的第一个元素位置索引 var lastIndex = ['tang','fu','qiang','fu'].lastIndexOf('fu'); // lastIndex为3// Array.from方法将俩类对象转化为真正的数组。 // 类似于数组的对象 和 可遍历(Iterable)的对象(包括ES6中的数据结构Set和Map) Array.from(new FormData(from))

对象API
Object.keys(obj)// 方法会返回由一个给定对象的自身【可枚举属性】组成的数组 var arr = ['a', 'b', 'c']; console.log(Object.keys(arr)); --- ['0', '1', '2']var obj = { 0: 'a', 1: 'b', 2: 'c' }; console.log(Object.keys(obj)); // console: ['0', '1', '2']var anObj = { 100: 'a', 2: 'b', 7: 'c' }; console.log(Object.keys(anObj)); // console: ['2', '7', '100']Object.assign()// 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。eg: Object.assign(target, ...sources)Object.getPrototypeOf(obj)// 返回指定对象的原型(内部[[Prototype]]属性的值) obj.hasOwnProperty(prop)// 返回一个布尔值,指示对象自身属性中是否具有指定的属性。 Object.create(创建对象的原型 , {对象自身可枚举属性(可选)} ) // eg: Object.create(Array.prototype) Object.defineProperty(Obj, prop, descriptor) // 返回被修改的对象 descriptor: value:默认undefined,该属性对应的值,可以是任何有限的JavaScript值,(函数、数字、对象等) writable:默认false,设置为true时value才能够被赋值运算符改变 configurable:默认为false不可修改,设置为true可以修改,也能删除该属性 enumerable:默认为false,设置为true该属性才能够出现在对象的枚举属性中//循环遍历: // for in: 遍历时候不仅能读取对象自身的成员属性,还可以读取原型链上对象的原型属性,所以可以使用hasOwnProperty判断一个属性是不是自身上的属性,返回true表示这个属性是对象的成员属性,不是原型属性 for(key in obj){ if(obj.hasOwnProperty(key)){ object[key] = 1; } }// for of:遍历所有数据机构的统一方法 // 一个数据结构只要部署了Symbol.iterator属性,就被视为具有iterator接口,就可以用for...of来遍历它的成员,也就是说,for...of循环内部调用的是数据结构的Symbol.iterator方法

日期API
const myDate = new Date([params]); // params可取值(月份0~11):空2019,9,20'2019/9/20' '2019-9-20''2019-9-20 17:27:30'myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份(4位,1970-????) myDate.getMonth(); //获取当前月份(0-11,0代表1月) myDate.getDate(); //获取当前日(1-31) myDate.getDay(); //获取当前星期X(0-6,0代表星期天) myDate.getTime(); //获取当前时间(从1970.1.1开始的毫秒数) myDate.getHours(); //获取当前小时数(0-23) myDate.getMinutes(); //获取当前分钟数(0-59) myDate.getSeconds(); //获取当前秒数(0-59) myDate.getMilliseconds(); //获取当前毫秒数(0-999) myDate.toLocaleDateString(); //获取当前日期 myDate.toLocaleTimeString(); //获取当前时间 myDate.toLocaleString( ); //获取日期与时间

总结 以上就是总结的javascript基础中一部分了,关于javascript基础还有很多内容,这边就不再详细介绍了,下一篇讲一下JS的事件循环(Event Loop),感兴趣的小伙伴可以关注一下,想要了解哪些内容也可以下方评论留言,以上内容如有错误也可以留言告知本人。ヽ( ̄▽ ̄)?
?

    推荐阅读