JS-基础

(1)基本数据类型

number,string,boolean,null,undefined,symbol以及未来ES10新增的BigInt(任意精度整数)七类。
引用数据类型(Object类)有常规名值对的无序对象{a:1},数组[1,2,3],以及函数等。

 number.toFixed()精度丢失----二进制浮点数表示法并不能精准表示十进制分数!JS采用二进制表示法,可以精确地表示二进制分数(1/2),但不能表示十进制分数(1/10)和像0.1这样的小数。

Math.round()四舍五入正确

Math.pow(2,5)求2的5次幂

保留小数的正确操作:

function toFixed(number,fractionDigits){
    var times = Math.pow(10, fractionDigits);
    var roundNum = Math.round(number * times) / times;
    return roundNum.toFixed(fractionDigits);
}

3==true 打印出什么

会打印出false,这里会将true转变成1。 1==true为true

Number 和 String 或者 Bool 类型比较,会对String 或者 Bool 类型进行ToNumber()转换

!!注意number转boolean时:!!0为false,!!1为true

箭头函数和function区别:

箭头函数是匿名函数,不能作为构造函数,不能使用new;

箭头函数不绑定arguments,取而代之用rest参数...解决;

箭头函数的this指向不变,一直指向定义时的上下文环境对象(指向定义时外层第一个普通函数的this, 当箭头函数外层没有普通函数时,它的this在严格和非严格模式都是指向window);function指调用自己的对象;

箭头函数没有原型属性;

箭头函数不能当做Generator函数,不能使用yield关键字

(2)变量及属性

        1、实例属性和原型属性:JavaScript-实例属性与原型属性区别_一起的远方的博客-CSDN博客

       2、属性的可枚举性和所有权:Object.defineProperty => https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

(3)判断元素是对象类型

       1. typeof(根据对象在底层存储的二进制来判断类型, 在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型, null 的二进制表示是全 0, 自然前三位也是 0, 所以执行 typeof 时会返回“object”)
判断字符串得到string,数字和NaN得到number,函数会得到function等,但是判断数组,对象和null时都会得到object
         2. instanceof(原型链)
可以用来判断一个变量是数组还是对象,数组也是对象的一种,使用instanceof都会返回true,但是对象instanceof Array返回false
        3. constructor
console.log(arr.constructor === Array); //true
console.log(arr.constructor === Object); //false
console.log(obj.constructor === Object); //true
        4. Object.prototype.toString.call()
可以精准判断变量类型,它返回[object constructorName]的字符串格式,这里的constructorName就是call参数的函数名
var res = Object.prototype.toString.call(arr);
console.log(res); //[object Array]
var res2 = Object.prototype.toString.call(obj);
console.log(res2); //[object Object]
var res3 = Object.prototype.toString.call(a);
console.log(res3); //[object Number]
var res4 = Object.prototype.toString.call(b);
console.log(res4); //[object String]
var res4 = Object.prototype.toString.call(c);
console.log(res4); //[object Null]
var res5 = Object.prototype.toString.call(d);
console.log(res5); //[object Boolean]
var res6 = Object.prototype.toString.call(e);
console.log(res6); //[object Undefined]
var res7 = Object.prototype.toString.call(f);
console.log(res7); //[object Symbol]
       5. 总结        
判断简单数据类型可以用typeof,判断数组,对象使用instanceof,constructor和 Object.prototype.toString.call(),最好使用Object.prototype.toString.call(),更加精准

 判断变量是不是数组的几个方法

var a=[];
a.constructor===Array //true
a instanceof Array === true //true

⚠️ 注意:以上方法在跨frame时会有问题,跨frame实例化的对象不共享原型

解决:

Object.prototype.toString.call(a) // "[object Array]"
Array.isArray(a) //true

(4)js对象的深拷贝

      首推的方法简单有效,JSON.stringfy()和JSON.parse()即可搞定。但是这种简单粗暴的方法有其局限性。当值为undefined、function、symbol 会在转换过程中被忽略。。。所以,对象值有这三种的话用这种方法会导致属性丢失
var syb = Symbol('obj');
var person = {
   name :'tino',
   say: function(){
      console.log('hi');
   },
   ok: syb,
   un: undefined
}
var copy = JSON.parse(JSON.stringify(person))
         2、当值为undefined、function、symbol 时
function deepCopy(obj) {
      var result = Array.isArray(obj) ? [] : {};
      for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
          if (typeof obj[key] === 'object' && obj[key]!==null) {
            result[key] = deepCopy(obj[key]);   //递归复制
          } else {
            result[key] = obj[key];
          }
        }
      }
      return result;
    }

(5)循环

for循环里要跳出整个循环是使用break,但在数组中用forEach循环如要退出整个循环呢?使用break会报错,使用return也不能跳出循环:
第一种:使用try···catch捕获异常实现
第二种方法:使用arr.some()或者arr.every()替代

js数组循环常用的几种方法_JiaPeng366的博客-CSDN博客

js的15种循环遍历,你掌握了几种?_诗人与黑客的博客-CSDN博客_js 循环

(6)数组操作

去重

      1. new Set()

ES6 新增了 Set 这一数据结构,类似于数组,但 Set 的成员具有唯一性。

function distinct(a, b) {
    return Array.from(new Set([...a, ...b]))
}
       2. for...of + Object

首先创建一个空对象,然后用 for 循环遍历

利用对象的属性不会重复这一特性,校验数组元素是否重复
function distinct(a, b) {
    let arr = a.concat(b)
    let result = []
    let obj = {}

    for (let i of arr) {
        if (!obj[i]) {
            result.push(i)
            obj[i] = 1
        }
    }

    return result
}

提取元素(同样适用于字符串):

slice(start,end)、splice(strt,end,index1,index2) 

1、slice()方法

 ---可以用来从数组中提取指定元素

 ---该方法不会改变元素数组,而是将截取到的元素封装到一个新数组中返回

参数:

1.截取开始的位置的索引,包含开始索引,省略默认从索引0开始

2.截取结束的位置的索引,不包含结束索引,省略默认到末尾

  -第二个参数可以忽略不写,此时会截取从开始索引往后的所有元素

  -索引可以传递一个负值,如果传递一个负值,则从后往前计算

  -1 倒数第一个

  -2 倒数第二个

**字符串中的substring()方法也可以截取字符串,跟slice()类似,不同的是这个方法不能直接接受负值作为参数,如果传递了一个负值,则默认使用0

substr和substring

语法:substr(start [,length]) 第一个字符的索引是0,start必选 length可选

   substring(start [, end]) 第一个字符的索引是0,start必选 end可选

相同点:当有一个参数时,两者的功能是一样的,返回从start指定的位置直到字符串结束的子串

不同点:有两个参数时

(1)substr(start,length) 返回从start位置开始length长度的子串

“goodboy”.substr(1,6);   //oodboy

【注】当length为0或者负数,返回空字符串

(2)substring(start,end) 返回从start位置开始到end位置的子串(不包含end)

“goodboy”.substring(1,6);  //oodbo

【注】:

(1)substring 方法使用 start 和 end 两者中的较小值作为子字符串的起始点

(2)start 或 end 为 NaN 或者负数,那么将其替换为0

2、splice() 方法

-可以用于删除数组中的指定元素

-使用splice()会影响到原数组,会将指定元素从原数组中删除,并将被删除的元素作为返回值返回

-参数:

  第一个,表示开始位置的索引

  第二个,表示删除的数量

  第三个及以后。。可以传递一些新的元素,这些元素将会自动插入到开始位置索引前边

增减元素

push(),向数组的末尾添加一个或多个元素,并返回新的数组长度。原数组改变。

pop(),删除并返回数组的最后一个元素,若该数组为空,则返回undefined。原数组改变。

unshift(),向数组的开头添加一个或多个元素,并返回新的数组长度。原数组改变

shift(),删除数组的第一项,并返回第一个元素的值。若该数组为空,则返回undefined。原数组改变。

数组扁平化

使多维数组变成一维数组

1、递归版本如下:

function flatter(arr) {
  if (!arr.length) return;
  return arr.reduce(
    (pre, cur) =>
      Array.isArray(cur) ? [...pre, ...flatter(cur)] : [...pre, cur],
    []
  );
}
// console.log(flatter([1, 2, [1, [2, 3, [4, 5, [6]]]]]));

2、迭代的思路

function flatten(arr) {
  if (!arr.length) return;
  while (arr.some((item) => Array.isArray(item))) {
    arr = [].concat(...arr);
  }
  return arr;
}
// console.log(flatter([1, 2, [1, [2, 3, [4, 5, [6]]]]]));

3、ES6中的flat([depth])函数

depth可选,指定要提取的嵌套数组的深度,默认值1。当参数为Infinity时,相当于扁平化最深层次

arr.flat(Infinity);
4、reduce和concat

function myFlat(arr, depth) {
  if (depth == 0) {
      return arr;
  }
  return arr.reduce((res, value)=>{
    if(Array.isArray(value)){
      res=res.concat(myFlat(value, depth-1));
    }else{
      res=res.concat(value);
    }
    return res;
  }, []);
}
var a = [1,2,3,[5,6,4, [8,9,10]]];
myFlat(a,1);

(7)点击事件阻止冒泡及默认行为

防止冒泡和捕获:w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true

当需要停止冒泡行为时,可以使用

function stopBubble(e) { 
//如果提供了事件对象,则这是一个非IE浏览器 
if ( e && e.stopPropagation ) 
    //因此它支持W3C的stopPropagation()方法 
    e.stopPropagation(); 
else 
    //否则,我们需要使用IE的方式来取消事件冒泡 
    window.event.cancelBubble = true; 
}

取消默认事件:w3c的方法是e.preventDefault(),IE则是使用e.returnValue = false;

javascript的return false只会阻止默认行为,而是用jQuery的话则既阻止默认行为又防止对象冒泡。

当需要阻止默认行为时,可以使用

//阻止浏览器的默认行为 
function stopDefault( e ) { 
    //阻止默认浏览器动作(W3C) 
    if ( e && e.preventDefault ) 
        e.preventDefault(); 
    //IE中阻止函数器默认动作的方式 
    else 
        window.event.returnValue = false; 
    return false; 
}

(8)修改元素属性:

* 使用jquery操作元素的css样式(获取、修改等等)
//1、获取和设置样式

$("#tow").attr("class")获取ID为tow的class属性

$("#two").attr("class","divClass")设置Id为two的class属性。

//2、追加样式

$("#two").addClass("divClass2")为ID为two的对象追加样式divClass2

//3、移除样式

$("#two").removeClass("divClass")移除 ID为two的对象的class名为divClass的样式。

$(#two).removeClass("divClass divClass2")移除多个样式。

//4、切换类名

$("#two").toggleClass("anotherClass") //重复切换anotherClass样式

//5、判断是否含有某项样式

$("#two").hasClass("another")==$("#two").is(".another");

//6、获取css样式中的样式

$("div").css("color") 设置color属性值. $(element).css(style)

//设置单个样式

$("div").css("color","red")

//设置多个样式

$("div").css({fontSize:"30px",color:"red"})

$("div").css("height","30px")==$("div").height("30px")

$("div").css("width","30px")==$("div").height("30px")

//7.offset()方法

//它的作用是获取元素在当前视窗的相对偏移,其中返回对象包含两个属性,即top和left 。

//注意:只对可见元素有效。

var offset=$("div").offset();

var left=offset.left;         //获取左偏移

var top=offset.top;        //获取右偏移

//8、position()方法

//它的作用是获取元素相对于最近的一个position样式属性设置为relative或者absolute的祖父节点的相对偏移,与offset()一样,它返回的对象也包括两个属性即top和left。

//9、scrollTop()方法和scrollLeft()方法

$("div").scrollTop();        //获取元素的滚动条距顶端的距离。

$("div").scrollLeft();         //获取元素的滚动条距左侧的距离。

//10、jQuery中的 toggle和slideToggle 方法,都可以实现对一个元素的显示和隐藏。区别是:

//toggle:动态效果为从右至左。横向动作。

//slideToggle:动态效果从下至上。竖向动作。

//比如想实现一个树由下至上收缩的动态效果,就使用slideToggle就ok了。

$('input').attr("readonly",true)//将input元素设置为readonly
$('input').attr("readonly",false)//去除input元素的readonly属性
$('input').attr("disabled",true)//将input元素设置为disabled
$('input').attr("disabled",false)//去除input元素的disabled属性

(9)Get与Post的区别

  • GET在浏览器回退时是无害的,而POST会再次提交请求。
  • GET产生的URL地址可以被Bookmark,而POST不可以。
  • GET请求会被浏览器主动cache,而POST不会,除非手动设置。
  • GET请求只能进行url编码,而POST支持多种编码方式。
  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
  • GET请求在URL中传送的参数是有长度限制的,而POST么有。GET方法提交的url参数数据大小没有限制,在http协议中没有对url长度进行限制,这个限制是特定的浏览器及服务器对他的限制
  • 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。get提交数据还可能会造成CSRF攻击
  • GET参数通过URL传递,POST放在Request body中。

(10)jQuery的deferred对象

jQuery的回调函数解决方案;$.when的参数只能是deferred对象

$.ajax()操作完成后,如果使用的是低于1.5.0版本的jQuery,返回的是XHR对象,你没法进行链式操作;如果高于1.5.0版本,返回的是deferred对象,可以进行链式操作。

jQuery的deferred对象详解 - 阮一峰的网络日志

(11)javascript中的关键字this: 

javascript中的关键字this_知其白,守其黑;和其光,同其尘。-CSDN博客

面向对象语言中 this 表示当前对象的一个引用。
但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。
1、在对象方法中, this 指向调用它所在方法的对象。
2、单独使用 this,它指向全局(Global)对象。
3、函数使用中,this 指向函数的所属者。
4、严格模式下函数是没有绑定到 this 上,这时候 this 是 undefined。
5、在 HTML 事件中,this 指向了接收事件的 HTML 元素。
6、apply 和 call 允许切换函数执行的上下文环境(context),即 this 绑定的对象,call() 和 apply() 方法可以将 this 引用到任何对象。
箭头函数 => 改变的并非把 this 局部化,而是完全不把 this 绑定到里面去

(12)js封装组件

1、js封装组件的原理:https://blog.csdn.net/sunshao904/article/details/95162104?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param(怎样用原生JS封装自己需要的插件,bootstrap是个借鉴)

jquery组件的扩展和封装(无界面css):JS组件系列——封装自己的JS组件,你也可以

另外,带界面css的组件:原生JavaScript实现一个简单的组件化Tab_超的博客-CSDN博客(原生JavaScript实现一个简单的组件化Tab)

(13)节流和防抖:

TS vs RXJS 中的防抖和节流 - 知乎

防抖debounce当一个事件持续触发时,指定间隔时间内没有再触发该事件,事件处理函数才会执行。如果在间隔时间之内重新触发了该事件,则重新开始计时。

节流throttleTime当一个事件持续触发时,保证一定时间内只执行一次

区别:

函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。

(14)安全:XSS 和 CSRF

XSS 和 CSRF简述及预防措施_我的博客-CSDN博客_csrf xss

(15)Dom节点类型

深入理解DOM节点类型第一篇——12种DOM节点类型概述 - 小火柴的蓝色理想 - 博客园

(16)如何解决前端跨域问题

通过nginx反向代理

采用nginx反向代理能很好的实现跨域,目前我的项目就是采用的这种方式。

​ 先做以下假设:

​ 我的服务器域名为 www.simple.com ip为:100.100.100.100

​ 前端项目部署在100.100.100.100:80

​ 后端项目部署在100.100.100.100:8080

​ 那么为了实现跨域,我可以这么配置我的nginx。

​ https://www.simple.com => 100.100.100.100:80

​ https://www.simple.com/api => 100.100.100.100:8080

​ 当前端项目要请求接口的时候,可以通过https://www.simple.com/api进行请求,完美跨域。

 (17)项目部署

使用jenkins进行前端项目自动部署 - 小火柴的蓝色理想 - 博客园

(18) 页面加载优化(减少白屏时间)

webpack-analysis-plugin --- 减少打包体积--moment.js、懒加载模块

js异步加载

html5、css3

html5 有哪些新特性

拖拽释放(Drag and drop) API

语义化更好的内容标签(header,nav,footer,aside,article,section)

音频、视频 API(audio,video)

画布(Canvas) API

地理(Geolocation) API

本地离线存储(localStorage) 长期存储数据,浏览器关闭后数据不丢失;

会话存储(sessionStorage),数据在浏览器关闭后自动删除

表单控件,calendar、date、time、email、url、search

新的技术 webworker, websocket, Geolocation

css3:

margin合并问题

在正常布局流中上下两个含有内容的div的margin会发生合并,合并后的margin值为相对大的值,当div内容为空时也会自动忽略其margin

CSS3有哪些新特性?新增属性有哪些?(总结) (gxlcms.com)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值