JS 常见知识点 (基础篇)

JS基础

1. 数据类型

基本类型:Number Boolean String undefined null  symbol

引用类型:Object Function Array(说到底都是Object )

1-2 检测数据类型

1 typeof :

 检测基本数据类型

2 instanceof :

	判断复杂数据类型
	
例: var arr =[3,2,1]
	console.log(arr  instanceof Array)		
	判断正确返回true,判断错误返回false

3 Array.isArray([])

 	Array.isArray() 用于确定传递的值是否是一个 Array。

例:Array.isArray([1, 2, 3]);  // true
	Array.isArray({foo: 123}); // false

4.Object.prototype.toString

   比较全面
console.log(Object.prototype.toString.call(arr))
// object Array

2. null和undefined

console.log(null==undefined);   //true  因为两者都默认转换成了false
console.log(typeof undefined);  //"undefined"  
console.log(typeof null);       //"object"  
console.log(null===undefined);  //false  null和undefined类型是不一样的,所以输出“false”

null表示没有对象,即该处不应该有值

作为函数的参数,表示该函数的参数不是对象   
作为对象原型链的终点   

undefined表示缺少值,即此处应该有值,但没有定义

定义了形参,没有传实参,显示undefined   
对象属性名不存在时,显示undefined   
函数没有写返回值,即没有写return,拿到的是undefined   
写了return,但没有赋值,拿到的是undefined   

null和undefined转换成number数据类型   
null 默认转成 0   
undefined 默认转成 NaN

undefined 代表的含义是未定义,null 代表的含义是空对象。一般变量声明了
但还没有定义的时候会返回 undefined,null
	
主要用于赋值给一些可能会返回对象的变量,作为初始化。

当我们对两种类型使用 typeof 进行判断的时候,Null 类型化会返回 “object”,
这是一个历史遗留的问题。
当我们使用双等号对两种类型的值进行比较时会返回 true,使用三个等号时会返回 false。

3 普通函数 和 箭头函数

普通函数

1.this 指向window
2.需要返回值

箭头函数

 1.this 指向父级作用域,固定的
 2.不需要返回值,可以隐式返回
 3.不能返回arguments对象
 4.语法简单
 5.不能作为构造函数,不能使用new,

用处特点:
简洁,用于简单逻辑中,

4 this指向

 1 函数中this指向window,
 2 定时器和延时器指向window
 3 对象中方法指向当前节点
 4 DOM1级中函数指向当前节点,
 5 箭头函数,指向宿主对象
 6.构造函数中this指向构造函数的实例

在这里插入图片描述

5 改变this指向

bind

 函数名.bind(新的this指向,实参1,实参2);
 功能:
    1.返回一个新的函数
    2.bind不会立即调用

call

 函数名.call(新的this指向,实参1,实参2)
功能:
    1.直接调用
    2.将函数内部的this指向第一个参数的对象
    3.将第二个及以后所有的参数,作为实参传递给函数

apply
主要用途是直接用数组传参

 函数名.apply(新的this指向, 数组/伪数组);
功能:
    1.直接调用
    2.将函数内部的this指向第一个参数的对象
    3.将第二个参数中的数组(伪数组)中的元素,拆解开依次的传递给函数作为实参

总结:

apply 参数是个数组
bind 不会立即调用,返回一个函数
call apply 直接调用

在这里插入图片描述

6 let const

let

1.具有块级作用域
2.没有变量提升
3.具有暂时性死局特性
 4.let不能重复声明 ,可修改

const

 1.具有块级作用域
 2.声明常量必须要赋初始值 
 3 .赋值后,不能修改.
varletconst
函数级作用域块级作用域块级作用域
变量提升不存在变量提升不存在变量提升
值可更改值可更改值不可更改

let const 的使用场景

如非特殊需要,所有的var 都可以改成let
如果声明一个再也不会被改变的变量,使用const

7 解构赋值

解构赋值的拷贝是浅拷贝,即如果一个键的值是复合类型的值(数组、对象、函数)、那么解构赋值拷贝的是这个值的引用,而不是这个值的副本。

//数组:
let arr =[3,4,5,6];
let [sex,age,num,abc]= arr
console.log(age)

//对象
let obj = { a: { b: 1 } };
let { ...x } = obj;
    obj.a.b = 2;
    x.a.b // 2

8 展开运算符(…)

1.将数组转化为参数序列

let arr =[1,2,3,4]
console.log(arr)  //[1,2,3,4]
console.log(...arr) //1 2 3 4

2.数组或对象 的合并

let arr1 =[1,2]
let arr2 =[3,4]

let arr4 =[...arr1,...arr2]
console.log(arr4)  //[1,2,3,4]

3.当做函数的参数使用

function fn(a,b,c){
   console.log(a,b,c)
}
let arr5=[1,2,3]
fn(...arr5) //1,2,3

4.将传递参数变成数组

function fn2(...arr){
   console.log(arr)
}
fn(1,2,3) //[1,2,3]

5.实现深拷贝

let obj={
    name:'zs',
    age:18
}
let obj1 = {...obj}
obj.age = 12
console.log(obj)   //name:'zs',age:18
console.log(obj1)  //name:'zs',age:12

9 伪数组? 如何转换为真数组?

什么是伪数组?

1.具有length属性,可以获取长度。
2.具有索引,可以通过遍历获取所有元素。
3.不可以使用数组的内置方法和属性。

常见的伪数组

1.函数的内置对象arguments,它是所有实参组成的伪数组。
2.DOM对象组成的伪数组,通过document.querySelectorAll等获得的dom对象列表。
3.jQuery对象组成的伪数组,通过$('选择器')获取到的包含dom对象列表和jQuery方法的jQuery对象

将伪数组转化为真数组的几种方法

方法一:最简单的,先准备一个新的空数组,然后遍历伪数组,将伪数组中的值通过索引逐个添加到新数组当中。

  let newArr = [];
  for(let i = 0; i < arguments.length; i++){
      newArr[i] = arguments[i];
  }

方法二:利用扩展运算符(…)将伪数组转化为真数组 - ES6语法

  let divs = document.querySelectorAll('div');
  let arr = [...divs];

方法三:利用Array.from方法 - ES6

let arr = Array.from(divs);

10 json 语法

.stringfy()

对象转化json字符串
JSON.stringfy()

.parse() json

字符串转换对象
JSON.parse()

11 新增的数据结构 set map

new Set(数组)

typeof 为object   但是成员的值都是唯一的,没有重复的值。

可以用做数组去重

var arr=[1,3,2,1,3,2,3,1]
var s =new Set(arr)

var sArr =[]
for (var i of s){
	sArr.push(i)
}
console.log(sArr)
var arr=[1,3,2,1,3,2,3,1]
var s = [...new Set(arr)]
console.log(sArr)

new Map() 映射

typeof 为object 它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

(映射 是一个键值对的结构,他的键可以是一个对象)

12 遍历

forEach 遍历数组

arr.forEach(function(v值,k下标,数组自身){}) 

当我们数组内存储的是对象类型的值时,遍历数组,对item进行操作,是会改变数组内的值的。
当我们数组内存储的是基本数据类型的值时,遍历数组对item进行操作,不会改变数组内的值。

map 遍历数组 不会改变原数组

var res = arr.map(function(v,k){
    return v*1.3
})
map () 方法会得到一个新的数组并返回

for of 遍历数组 es6

var (var v of arr){}

for in 遍历数组或对象 得到对象的key 或数组,字符串的下标

var (var v in arr){}

13 新增数组方法

Array.from()

可以把伪数组转换为真数组

Array.map(函数)

let a = [1,2,3,4,5];
let b = a.map(item => item * 2);
console.log(b) // [2,4,6,8,10]
返回一个全新的数组,不会改变原是数组 不会对空数组进行检测

Array.filter()

let array= list.filter(
  (item) => item.status !== '草稿'
)
创建一个新的数组,新数组检查指定数组中符合条件的所有元素。

Array.find(callback)

let a = [1,2,3,4,5];
let b = a.find(item => item > 2);
console.log(b) // 3
返回数组中符合条件的第一个元素

Array.findIndex(callback) / Array.indexOf()

let a = [1,2,3,4,5];
let b = a.every(item => item > 2);
返回数组中符合条件的第一个元素的索引值,否则就返回-1

Array.every(callback)

判断数组中所有的元素都符合条件时,返回true

Array.some(callback)

let a = [1,2,3,4,5];
let b = a.some(item => item > 2);
console.log(b) // true
判断数组中有一个元素符合条件,就返回true

Array.includes(item, finIndex)

这个方法是判断数组中是否包含有指定的值,包含就返回true,否则就是false,
它接受两个参数,第一个为搜索的值(必填),第二个为搜索开始的位置(选填,默认从0开始)

第一种 

let a = [1,2,3];
let b = a.reduce((i, j) => {
  return i + j;
}, 0);
console.log(b) // 6

第二种 
let a = [1,2,3];
let b = a.reduce((i,j) => {
	i.push(j)
	return i
},[0])
console.log(b) // [0,1,2,3]

14 数组增删改查

1,push() 尾部增

let a =[1,2,3,4]
a.push(6,7,8) // 原数组变为[1,2,3,4,6,7,8]
 注:1,在原数组后面添加一个或多个成员,返回新的数组长度
	 2,改变原数组

2,unshift() 头部增

let a =[1,2,3,4]
a.unshift(6,7,8) // 原数组变为[6,7,8,1,2,3,4]
 注:1,在原数组头部添加一个或多个成员,返回新的数组长度
 	 2,改变原数组

3,splice()添加

var arr = ['a','b']
arr.splice(1,0,'ttt')
console.log(arr) //['a','ttt','d']
注:1,例:在下标1处,添加ttt
	2,改变原数组

4,shift() 头部删

let a =[1,2,3,4]
a.shift() // 输出 1  原数组变为[2,3,4]
注:1,将数组的第一个元素从其中删除,并返回第一个元素的值。
 	2,改变原数组

5,pop尾部减

arr= [1,2,3,4,5]
arr.pop() // 5  原数组变为[1, 2, 3, 4]

注: 1,从末尾开始,删除最后一个,返回最后一个元素
    2,改变原数组

6,splice()删除

var arr =['a','b','c','d']
arr.splice(1,2)
console.log(arr) //['a','d']
注:1,例:从下标1开始,删除长度为22,改变原数组

7,splice() 替换

arr.splice(1,2,'ttt')
console.log(arr) //['a','ttt','d']
注:1,例  从项目1开始,替换2位,新ttt
    2,改变原数组

8,replace() 替换

obj='abcdefg'
obj.replace('a','b')
 // "bbcdefg"
注:1,用于字符串,参数1代表原数据,参数2代表新数据
    2,不改变原字符串
    
name = 'aaa bbb ccc';
name.replace(/\b\w+\b/g, function(word){
  return word.substring(0,1).toUpperCase()+word.substring(1);}
);

注:1,substring(0,1) 从第0个开始截取一个
	2,substring(1)截取第一位后面的所有

补充:

arr.sort()
数组重新排序

arr.reverse();
反转数组  

arr.join(str); 
转换为字符串 

arr.concat(arr1,arr2,...,arr3)
合并数组  concat 如果不赋值,则相当于复制

arr.slice(start,end) 分割数组

15 es6新增字符串方法

includes(str,start)  
判断字符串中,是否包含某个字符
start 代表着从第几个下标开始数

startsWith() 
字符串是否以某个字符开头

endsWith(str,end)  
字符串是否以某个字符结束

补充:

indexOf() 
查找字符串中某个元素

charAt() 
返回指定下标对应的字符

substring(n,m) / slice(n,m)
截取字符串

split()
截取标识符,会改变原始数组

replace(替换前,替换后)
替换元素

toUpperCase() 转换为大写
toLowerCase() 转换为小写
## 数据类型转换

```javascript
.stringfy() 对象转化json字符串
JSON.stringfy()

.parse()  json 字符串转换对象
JSON.parse()

15-1 对象去除键值对

delete  对象.对象方法

15-1 -2判断中某个属性是否存在

1.hasOwnProperty (只看对象本身有否)
2.in (ts)(可原型链)

15-2 数组去重

	function Uniq(arr = []) {
        return arr.reduce((t, v) => t.includes(v) ? t : [...t, v], []);
    };
    const arr = [2, 1, 0, 3, 2, 1, 2];
    Uniq(arr); //[2, 1, 0, 3]
    console.log(Uniq(arr));
     let set = new Set([4, 8, 9, 5, 4, 8, 4, 2]);
     console.log([..set]); //Set(5) {4,8,9,5,2}
     function unique(arr) {
        var newArr = [];
        for (var i = 0; i < arr.length; i++) {
            if (newArr.indexOf(arr[i]) === -1) {
                newArr.push(arr[i]);
            }
         }
         return newArr;
      }
      console.log(unique(['blue', 'green', 'blue'])) // ['green', 'blue']

15-3 数组扁平

    // 第一种  最快的方法时在arr.flat()方法里面接一个Infinity参数
    // 使用 Infinity 作为深度,展开任意深度的嵌套数组
    // flat() 方法会移除数组中的空项:
    let arr = [1, [2, [3, [4, 5, 3, [4, 5], 6, 2, 8]]], 6, 7]
    let arr_flat = arr.flat(Infinity)
    console.log(arr_flat)
    // 第二种处理, map()方法里面接Number参数可以将字符串数组转化为数字型数组
    console.log(arr.join(',').replace(/\[\]/g, '').split(',').map(Number))
     // 第三种扩展运算符处理
    while (arr.some(Array.isArray)) {
      arr = [].concat(...arr)
    }
    console.log(arr)
    // 第四种 reduce
    function Flat(arr = []) {
        return arr.reduce((t, v) => t.concat(Array.isArray(v) ? Flat(v) : v), []);
    };
    console.log(Flat(arr));

15-4. 数组排序

数组排序
sort() 方法以字母顺序对数组进行排序:

冒泡排序

1、比较相邻的两个元素,如果前一个比后一个大,则交换位置。
2、比较完第一轮的时候,最后一个元素是最大的元素。
3、这时候最后一个元素是最大的,所以最后一个元素就不需要参与比较大小。
    var arr = [1, 3, 5, 2, 4]
    
    for (var k = 0; k < arr.length - 1; k++) {
        for (var i = 0; i < arr.length - k - 1; i++) {
            if (arr[i] > arr[i + 1]) {
                var tep = arr[i]
                arr[i] = arr[i + 1]
                arr[i + 1] = tep
            }
        }
    } 
    console.log(arr);

选择排序

   var arr = [5, 4, 3, 2, 1]
    //  先创建一个最小的min[]
    var min = arr[0]
    var j = 0
    for (var i = 1; i < arr.length; i++) {
        if (min > arr[i]) {
            min = arr[i]
            j = i
        }
    }
    arr[j] = arr[0]
    arr[0] = min
    console.log(arr);

    //  先创建一个最小的min[]
    var min = arr[1]
    var j = 1
    for (var i = 2; i < arr.length; i++) {
        if (min > arr[i]) {
            min = arr[i]
            j = i
        }
    }
    arr[j] = arr[1]
    arr[1] = min
    console.log(arr);

    // 求最大值
    var arr = [1, 3, 5, 2, 4]
    var max = []

    for (i = 1; i < arr.length; i++) {
        if (max < arr[i]) {
            max = arr[i]
        }
    } 
    console.log(max);

插入排序

        function insert(arr) {
          // 1. 准备一个新数组,用来存储抓到手里的牌,开始先抓一张牌
          let handle = [];
          handle.push(arr[0]);
          // 2. 从第二项开始依次抓牌,一直到把台面上的牌抓光
          for (let i = 1; i < arr.length; i++) {
            let A = arr[i]; // 是新抓的牌
            // 和handle 里面的牌一次比较(从后向前比)
            for (let j = handle.length - 1; j >= 0; j--) {
              // 每次要比较手里的牌
              let B = handle[j]
              // 如果当前的新牌A 比要比较的牌B 大,把A 放到B 的后面
              if (A > B) {
                 handle.splice(j + 1, 0, A);
                 break;
              }
             // 已经比到第一项,把新牌放到手中最前面即可
             if (j === 0) {
               handle.unshift(A)
             }
          }
        }
       return handle
     }
    console.log(insert(arr));

15-5 数组转对象

const people = [
   { area: 'GZ', name: 'YZW', age: 27 },
   { area: 'SZ', name: 'TYJ', age: 25 }
];
const map = people.reduce((t, v) => {
    const { name, ...rest } = v;
    t[name] = rest;
    return t;
}, {});
console.log(map); // {YZW: {…}, TYJ: {…}}

15-6 递归实现深克隆

递归

在函数的内部执行自己
function fn(){
    fn()
}

2.特点:占内存

 低版本浏览器中会造成内存泄漏
 代码简洁

3.递归解决问题思路

递:向内执行
归:向外结束
  function deepClone(obj) {
     // 过滤特殊情况
    if (obj === null) return null;
    if (obj instanceof Function) {
         return new Function(obj)
     }
       if (typeof obj !== 'object') return obj;
       if (obj instanceof RegExp) {
         return new RegExp(obj);
       }
      if (obj instanceof Date) {
         return new Date(obj);
      }
       let newObj = new Object()
       // 不直接创建空对象 目的是克隆的结果和之前保持相同的所属类
       let newObj = new obj.constructor; // 防止obj的constructor更改;一个实例的constructor 指向它所有类;
     for (let key in obj) {
         if (obj.hasOwnProperty(key)) {
           newObj[key] = deepClone(obj[key]);
         };
     };
       return newObj;
   };

15-7 返回键值对形式的数组

    // 方式一 
     var obj = { a: 1, b: 2, c: 3, d: 4 }
     arr = Object.keys(obj).map((key, value) => [key, Object.values(obj)[value]])
     console.log(arr);
    // 方式二
     console.log(Object.entries(obj));

15-8 数组和对象的区别

    1. 数组表示有序数据的集合,而对象表示无序数据的集合(因为数组是一个特殊的对象,所有如果按照对象的方法操作数组,那么数组也可以是无序的)
    2. 数组是一个特殊的对象,数组具有对象的所有性质
    3. 数组有length 属性,而对象没有

16 事件委托 冒泡

事件冒泡:

触发子元素身上的事件,父元素身上的同等类型事件也会被触发,   
事件的触发顺序自内向外
        只能阻止同类型的事件。

阻止冒泡:

    event.stopPropagation();

阻止默认行为:

  1.e.preventDefault();  
  2.return flase  DOM1级
  3.<a href="javascript::"></a>
  4.stopDefault() 

事件委托:

利用冒泡的原理,将子元素的操作委托给父元素处理

 获取事件源  event.target

事件捕获:

事件触发顺序变更为自外向内、

解决方式:通过事件委托 event.target

17. BOM

 Browser Object Model 是浏览器对象模型
 window (浏览器窗口对象,主要用于操作浏览器,浏览器中最大的对象)
 location  地址栏对象 提供了对地址栏操作的方法和属性
 history 浏览历史对象,提供了对浏览器历史操作的方法和属性
 screen 屏幕对象 获取屏幕的信息
 navigator 浏览器对象,提供了获取浏览器信息的方法和属性
 document  文档对象,代表整个页面 DOM的根节点

一.window

获取浏览器宽度
var w = window.innerWidth;

获取浏览器高度
var h =  window.innerHeight;

二.history() 浏览历史对象

history.forward()前进
前进,需要后退一下之后,才有前进的方向,有历史记录才能前进

history.go(num)为0,刷新

history.back()后退,
加载前一个url。

history.length输出  
浏览过的历史长度

三.location 地址栏对象

location.href; 获取地址栏网址  

location.href  设置网址,
 location.href = 'http://www.taobao.com';重新打开一个页面
 
location.search; 获取参数

location.hash;获取#后的数据

location.reload();   刷新页面

四.onload 事件

onscroll 滚动事件
onresize 窗口事件

(堆栈,深浅拷贝,宏任务微任务,原型链)
https://blog.csdn.net/weixin_55042716/article/details/115140654?spm=1001.2014.3001.5501

18 DOM 增删改查

查找节点

document.getElementById('id属性值');
返回拥有指定id的第一个对象的引用

document/element.getElementsByClassName('class属性值');
返回拥有指定class的对象集合

document/element.getElementsByTagName('标签名');
返回拥有指定标签名的对象集合

document.getElementsByName('name属性值');
返回拥有指定名称的对象结合

document/element.querySelector('CSS选择器');
仅返回第一个匹配的元素

document/element.querySelectorAll('CSS选择器');
返回所有匹配的元素

document.documentElement
获取页面中的HTML标签

document.body
获取页面中的BODY标签

document.all['']
获取页面中的所有元素节点的对象集合型

新建节点

document.createElement('元素名');
创建新的元素节点

document.createAttribute('属性名');
创建新的属性节点

document.createTextNode('文本内容');
创建新的文本节点

document.createComment('注释节点');
创建新的注释节点

document.createDocumentFragment( );
创建文档片段节点

添加新节点

parent.appendChild( element/txt/comment/fragment );
向父节点的最后一个子节点后追加新节点

parent.insertBefore( newChild, existingChild );
向父节点的某个特定子节点之前插入新节点

element.setAttributeNode( attributeName );
给元素增加属性节点

element.setAttribute( attributeName, attributeValue );
给元素增加指定属性,并设定属性值

添加文本节点

1,document.createTextNode('新增文本内容');

例:var element = document.getElementsByTagName('p')[0]; 
	var txt =  document.createTextNode('新增文本内容'); //创建文本节点
	element.appendChild(txt); //添加文本节点


2,element.innerHTML='新增文本内容'; 

例:var element = document.getElementsByTagName('p')[0];
	element.innerHTML='新增文本内容'; //插入文本内容

删除节点

parentNode.removeChild( existingChild );
删除已有的子节点,返回值为删除节点

element.removeAttribute('属性名');
删除具有指定属性名称的属性,无返回值

element.removeAttributeNode( attrNode );
删除指定属性,返回值为删除的属性 

修改节点

parentNode.replaceChild( newChild, existingChild );
用新节点替换父节点中已有的子节点

element.setAttributeNode( attributeName );	
若原元素已有该节点,此操作能达到修改该属性值的目的

element.setAttribute( attributeName, attributeValue );	
若原元素已有该节点,此操作能达到修改该属性值的目的

添加属性节点,修改属性值:

1、element.setAttributeNode( attributeName );

例: var element = document.getElementsByTagName('p')[0];
 	element.setAttribute('id','idValue'); //添加属性节点
	element.setAttribute('class','classNewValue');//修改属性值



2. element.setAttribute( attributeName, attributeValue );

 例: var element = document.getElementsByTagName('p')[0];
 // 添加属性节点
     var attr = document.createAttribute('id'); 
     attr.value = 'idValue';
     element.setAttributeNode(attr); 

// 修改属性值
    var attr = document.createAttribute('class'); 
    attr.value = 'classNewValue';
    element.setAttributeNode(attr);
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王小王和他的小伙伴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值