2019-08-12 vue 深拷贝 浅拷贝 只能输入3的倍数

只能输入3的倍数



什么是深拷贝?浅拷贝 ?

 1.浅拷贝:浅拷贝是拷贝引用,拷贝后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响。

//这里的赋值仅仅只是把obj1的内存地址指向了obj。var obj={name:'zhangsan',age:24}var obj1=obj;

console.log(obj1.name);//zhangsan

//改变obj1中name的值,obj中name的值也跟着发生改变

obj1.name='lisi';

console.log(obj.name)//lisi

consloe.log(obj1.mane)//lisi


像上面这种直接赋值的方式就是浅拷贝,此时会发现,obj1的值发生改变,原来的obj也会跟着发生改变。但是很多情况下我们想要的不是这种情况,仅仅只是把原对象的值拷贝过来当改变obj1时,obj并不需要跟着改变。此时,就需要用到了深拷贝。

2.深拷贝:在堆中重新分配内存,并且把源对象所有属性都进行新建拷贝,以保证深拷贝的对象的引用图不包含任何原有对象或对象图上的任何对象,拷贝后的对象与原来的对象是完全隔离,互不影响。

//深拷贝就是不紧复制对象的基本类,同时也复制原对象中的对象.//就是说完全是新对象产生的,新对象所指向的不是原来对像的地址。


function deepCopy(a, b) {

  var b = b || {};

  for (var i in a) {

    if (typeof a[i] === 'object') {

      b[i] = (a[i].constructor === Array) ? [] : {};

      deepCopy(a[i], b[i]);

    } else {

       b[i] = a[i];

    }

  }

  return b;

}

var arr =['zhangsan','lisi','wangwu'];var newArr=deepCopy(arr,newArr);


console.log(arr[1]);//lisi

console.log(newArr[1]);//lisi


newArr[1]='zhaoliu';

console.log(arr[1]);//lisi

console.log(newArr[1]);//zhaoliu



数组去重?

  方法一:

双层循环,外层循环元素,内层循环时比较值

如果有相同的值则跳过,不相同则push进数组


Array.prototype.distinct = function(){

 var arr = this,

  result = [],

  i,

  j,

  len = arr.length;

 for(i = 0; i < len; i++){

  for(j = i + 1; j < len; j++){

   if(arr[i] === arr[j]){

    j = ++i;

   }

  }

  result.push(arr[i]);

 }

 return result;

}

var arra = [1,2,3,4,4,1,1,2,1,1,1];

arra.distinct();    //返回[3,4,2,1]

方法二:利用splice直接在原数组进行操作

双层循环,外层循环元素,内层循环时比较值

值相同时,则删去这个值

注意点:删除元素之后,需要将数组的长度也减1.


Array.prototype.distinct = function (){

 var arr = this,

  i,

  j,

  len = arr.length;

 for(i = 0; i < len; i++){

  for(j = i + 1; j < len; j++){

   if(arr[i] == arr[j]){

    arr.splice(j,1);

    len--;

    j--;

   }

  }

 }

 return arr;

};

var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,];

var b = a.distinct();

console.log(b.toString()); //1,2,3,4,5,6,56

优点:简单易懂

缺点:占用内存高,速度慢

方法三:利用对象的属性不能相同的特点进行去重


Array.prototype.distinct = function (){

 var arr = this,

  i,

  obj = {},

  result = [],

  len = arr.length;

 for(i = 0; i< arr.length; i++){

  if(!obj[arr[i]]){ //如果能查找到,证明数组元素重复了

   obj[arr[i]] = 1;

   result.push(arr[i]);

  }

 }

 return result;

};

var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,];

var b = a.distinct();

console.log(b.toString()); //1,2,3,4,5,6,56

方法四:数组递归去重

运用递归的思想

先排序,然后从最后开始比较,遇到相同,则删除


Array.prototype.distinct = function (){

 var arr = this,

  len = arr.length;

 arr.sort(function(a,b){  //对数组进行排序才能方便比较

  return a - b;

 })

 function loop(index){

  if(index >= 1){

   if(arr[index] === arr[index-1]){

    arr.splice(index,1);

   }

   loop(index - 1); //递归loop函数进行去重

  }

 }

 loop(len-1);

 return arr;

};

var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,56,45,56];

var b = a.distinct();

console.log(b.toString());  //1,2,3,4,5,6,45,56

方法五:利用indexOf以及forEach


Array.prototype.distinct = function (){

 var arr = this,

  result = [],

  len = arr.length;

 arr.forEach(function(v, i ,arr){  //这里利用map,filter方法也可以实现

  var bool = arr.indexOf(v,i+1);  //从传入参数的下一个索引值开始寻找是否存在重复

  if(bool === -1){

   result.push(v);

  }

 })

 return result;

};

var a = [1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,2,1,23,1,23,2,3,2,3,2,3];

var b = a.distinct();

console.log(b.toString()); //1,23,2,3

方法六:利用ES6的set

Set数据结构,它类似于数组,其成员的值都是唯一的。

利用Array.from将Set结构转换成数组


function dedupe(array){

 return Array.from(new Set(array));

}

dedupe([1,1,2,3]) //[1,2,3]

拓展运算符(...)内部使用for...of循环


let arr = [1,2,3,3];

let resultarr = [...new Set(arr)];

console.log(resultarr); //[1,2,3]

下面给大家补充介绍合并数组并去重的方法

一、concat()方法

思路:concat() 方法将传入的数组或非数组值与原数组合并,组成一个新的数组并返回。该方法会产生一个新的数组。


function concatArr(arr1, arr2){

  var arr = arr1.concat(arr2);

  arr = unique1(arr);//再引用上面的任意一个去重方法

  return arr;

}

二、Array.prototype.push.apply()

思路:该方法优点是不会产生一个新的数组。


var a = [1, 2, 3];

var b = [4, 5, 6];

Array.prototype.push.apply(a, b);//a=[1,2,3,4,5,6]

//等效于:a.push.apply(a, b);

//也等效于[].push.apply(a, b);

function concatArray(arr1,arr2){

  Array.prototype.push.apply(arr1, arr2);

  arr1 = unique1(arr1);

  return arr1;

}



排序?

     (1)选择排序(从小到大)

         1)思想:选择排序,让数组中的每一个数,依次与后面的数进行比较,如果前面的数大于后面的数,就进行位置的交换。这种说法或许有些人看不明白。换个说法,选择排序:第一个数依次与

                  后面的数比较,第一次比较完之后最小的数在最前面 。

          不理解的看看图应该就差不多了,真不明白就和明白的人讨论讨论吧。




         2)代码

                 import java.util.Arrays;

                 /**

                  * 练习排序-选择排序

                  * @author Administrator

                  *

                  */

                 public class Dome2 {

                            public static void main(String[] args) {

                                 //数组

                                 int[] arr = {5,3,7,2,6,7,6,5,4,1,9,8};

                                //第一次循环,是确定一个数依次和后面数的比较的数。

                                for (int i = 0; i < arr.length -1 ; i++) {

                                   //这个是和第一个数的比较的数

                                    for (int j = i+1; j < arr.length; j++) {

                                      //定义一个临时的变量,用来交换变量

                                       int temp ;  

                                       if(arr[i]>arr[j]){

                                            temp =  arr[i];

                                            arr[i] = arr[j];

                                            arr[j] = temp;

                                       }

                                   }

                                }

                        //打印最后的排序结果

                        System.out.println(Arrays.toString(arr));

                         }

                }

  (2)冒泡排序(从小到大)    

         1)思想:相邻两个数进行比较,第一波比较后,最大的数在最后。(每比较完之后,后面的数就减少一个比较 )



         2)代码

            import java.util.Arrays;

           /**

            * 练习排序--冒泡排序

            * @author Administrator

            *

            */

              public class Dome2 {

                    public static void main(String[] args) {

                       //数组

                       int[] arr = {5,3,7,2,6,7,6,5,4,1,9,8};

                       //外部循环

                       for(int i=0;i<arr.length-1;i++){

                            //相连两个数的索引是利用内部循环

                            for(int index=0;index<arr.length-1;index++){

                            //同样利用中间变量,注意区分与选择排序的区分

                                 if(arr[index]>arr[index+1]){

                                     int temp=arr[index];

                                     arr[index]=arr[index+1];

                                     arr[index+1]=temp;

                                }

                           }

                       }

                        System.out.println(Arrays.toString(arr));

                 }

             }




Vue路由拦截?

  点击登录的时候向后台发送一个请求,后台会返回一个状态,把这个状态存到本地存储里,利用导航守卫的生命周期()中的参数to(即将进入的路径)  from(从哪个路径来,到那个路径去),把想要跳转的路径放在一个数组里,把他的name属性放在from中,如果有的话,跳转到相应的页面,如果没有的话,跳转到登录页面 ;


Vue组件通信?

分三种 父传子 子传父 兄弟传参

父传子 就是props向下传递 事件向上传递 父组件通过props给子组件下发数据

子传父 子组件通过$emit接收父组件传递过来的自定义事件名和数据

兄弟传参 先子传父 再父传子

需要定义一个公共组件 作为仓库来传值 不然路由组件达不到传值效果


Vue生命周期?


beforeCreate:表示组件实例刚刚被创建,组件属性计算之前,如data属性等

created:表示组件实例创建完成,属性已经绑定但是页面上的dom元素还未生成,$el属性还不存在

beforeMount:表示组件模板编译和挂载之前

mounted:表示组件模板编译和挂载之后

beforeUpdate:表示组件更新之前

updated:表示组件更新之后

beforeDestroy:表示组件销毁之前

destroyed:表示组件组件销毁之后


React生命周期?

  react生命周期函数

这个问题要考察的是组件的生命周期

一、初始化阶段:

getDefaultProps:获取实例的默认属性

getInitialState:获取每个实例的初始化状态

componentWillMount:组件即将被装载、渲染到页面上

render:组件在这里生成虚拟的DOM节点

componentDidMount:组件真正在被装载之后

二、运行中状态:

componentWillReceiveProps:组件将要接收到属性的时候调用

shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回false,接收数据后不更新,阻止render调用,后面的函数不会被继续执行了)

componentWillUpdate:组件即将更新不能修改属性和状态

render:组件重新描绘

componentDidUpdate:组件已经更新

三、销毁阶段:

componentWillUnmount:组件即将销毁


双向数据绑定原理:Vue:通过Object.defineProperty实现数据劫持:先创建一个Observe监听器劫持所有的属性,如果属性有变化就通知订阅者;然后watcher收到属性的变化,就触发相关的方法函数,从而更新视图

.Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。



总体来说vue-router里面提供了三大类钩子

全局钩子

某个路由独享的钩子

组件内构子

而且其中三种钩子都涉及到了三个参数

分别为

To:Route即将要进入的目标 路由对象

From:route 当前导航正要离开的路由

Next:function 一定要调用该方法来resolve这个钩子,执行效果依赖next方法的调用参数

一:全局守卫(全局路由钩子)router.beforeEach  注意使用全局路由钩子一定要调用next

()

二:路由内独享的守卫(路由内钩子)beforeEnter守卫 你可以在路由配置上直接定义beforeEnter守卫

组件内的守卫(组件内钩子)

最后你可以在组件中直接定义一下路由导航守卫

beforeRouteEnter

在渲染该组件的对应路由被confirm前调用

不能获取组件实列 this,因为当守卫执行前,组件实列还没有被创建

beforeRouteUpdate 2.2版本新增

在当前路由改变,但是该组件被重复时调用

举例来说,对于一个带有动态参数的路径/foo/:id,在/foo/1和/foo/2之间跳转时由于会渲染同样的foo组件,因此组件实例会被复用,而这个钩子就会在这个情况下调用

可以访问组件实例

beforeRouteleave

导航离开该组件的对应路由时调用 可以访问组件实列

4题 拖拽的基本原理就是根据鼠标的移动来移动被拖拽的元素。鼠标的移动也就是x、y坐标的变化;元素的移动就是style.position的 top和left的改变。当然,并不是任何时候移动鼠标都要造成元素的移动,而应该判断鼠标左键的状态是否为按下状态,是否是在可拖拽的元素上按下的。

vue项目的优化


所谓的基础优化是任何项目都想要做的,基本上的话都是从html css js 是第一步要优化的点分别对应文件内的<template/>,<style>,<script>

1. 语义化标签,避免乱嵌套,合理命名属性

2. vue通过数据驱动视图,主要注意以下几点

· 答:v-show,v-if 用哪个?在我来看要分两个维度去思考问题,第一个维度是权限问题,只要涉及到权限相关的展示无疑要用 v-if,第二个维度在没有权限限制下根据用户点击的频次选择,频繁切换的使用 v-show,不频繁切换的使用 v-if,这里要说的优化点在于减少页面中 dom 总数,我比较倾向于使用 v-if,因为减少了 dom 数量,加快首屏渲染,至于性能方面我感觉肉眼看不出来切换的渲染过程,也不会影响用户的体验。

· 不要在模板里面写过多的表达式与判断 v-if="isShow && isAdmin && (a || b)",这种表达式虽说可以识别,但是不是长久之计,当看着不舒服时,适当的写到 methods 和 computed 里面封装成一个方法,这样的好处是方便我们在多处判断相同的表达式,其他权限相同的元素再判断展示的时候调用同一个方法即可。

· 循环调用子组件时添加 key,key 可以唯一标识一个循环个体,可以使用例如 item.id 作为 key,假如数组数据是这样的 ['a' , 'b', 'c', 'a'],使用 :key="item" 显然没有意义,更好的办法就是在循环的时候 (item, index) in arr,然后 :key="index"来确保 key 的唯一性。

Style

· 将样式文件放在 vue 文件内还是外?讨论起来没有意义,重点是按模块划分,我的习惯是放在 vue 文件内部,方便写代码是在同一个文件里跳转上下对照,无论内外建议加上 <style scoped> 将样式文件锁住,目的很简单,再好用的标准也避免不了多人开发的麻烦,约定命名规则也可能会冲突,锁定区域后尽量采用简短的命名规则,不需要 .header-title__text 之类的 class,直接 .title 搞定。

· 为了和上一条作区分,说下全局的样式文件,全局的样式文件,尽量抽象化,既然不在每一个组件里重复写,就尽量通用,这部分抽象做的越好说明你的样式文件体积越小,复用率越高。建议将复写组件库如 Element 样式的代码也放到全局中去。

· 不使用 float 布局,之前看到很多人封装了 .fl -- float: left 到全局文件里去,然后又要 .clear,现在的浏览器还不至于弱到非要用 float 去兼容,完全可以 flex,grid 兼容性一般,功能其实 flex 布局都可以实现,float 会带来布局上的麻烦,用过的都知道不相信解释坑了

Script

· 多人开发时尽量保持每个组件 export default {} 内的方法顺序一致,方便查找对应的方法。我个人习惯 data、props、钩子、watch、computed、components。

· data 里要说的就是初始化数据的结构尽量详细,命名清晰,简单易懂,避免无用的变量,isEditing 实际可以代表两个状态,true 或 false,不要再去定义 notEditing 来控制展示,完全可以在模板里 {{ isEditing ? 编辑中 : 保存 }}

· props 父子组件传值时尽量 :width="" :heigth="" 不要 :option={},细化的好处是只传需要修改的参数,在子组件 props 里加数据类型,是否必传,以及默认值,便于排查错误,让传值更严谨。

· 钩子理解好生命周期的含义就好,什么时间应该请求,什么时间注销方法,哪些方法需要注销。简单易懂,官网都有写。

· metheds 中每一个方法一定要简单,只做一件事,尽量封装可复用的简短的方法,参数不易过多。如果十分依赖 lodash 开发,methed 看着会简洁许多,代价就是整体的 bundle 体积会大,假如项目仅仅用到小部分方法可以局部引入 loadsh,不想用 lodash 的话可以自己封装一个 util.js 文件

· watch 和 computed 用哪个的问题看官网的例子,计算属性主要是做一层 filter 转换,切忌加一些调用方法进去,watch 的作用就是监听数据变化去改变数据或触发事件如 this.$store.dispatch('update', { ... })

打包优化

解决方法很简单,打包 vender 时不打包 vue、vuex、vue-router、axios 等,换用国内的 bootcdn 直接引入到根目录的 index.html 中。

在 webpack 里有个 externals,可以忽略不需要打包的库

externals: {

  'vue': 'Vue',

  'vue-router': 'VueRouter',

  'vuex': 'Vuex',

  'axios': 'axios'

}

vue列表渲染性能优化的原理

答:vue是一个高效的mvvm框架,这得益于作者已经帮我们框架内部做了足够的优化,

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358

推荐阅读更多精彩内容