js数组排序 检测是否为公有属性 拆箱装箱 机制链

JS 插入、快排算法(数组排序)、面向对象等等

以下内容全部干货 废话不多少直接上算法

算法—-

数组的插入:

先给大家说一下计算的思想;我们先把数组比做成打扑克牌;

 let arr = [12, 43, 23, 56, 97, 26]; 当作桌上的牌
 第一步我们先抓一张牌到手上【第一张】
 let handle = [12] //let一个变量放第一张牌
 第二步:依次抓取桌面上剩下的牌,每一次抓牌后都和手里的每一张比较
 【个人习惯从后往前】 我们把新抓的牌当 A 手里要比较的牌是 B
 如果A > B 我们就把A 放到 B的后面 ..
 如果转的牌比手里任何一张都要小,我们九八新抓的牌放在手里最前面;
 A=8
 8 VS 一开始抓的12  handle=[8,12]
 A=15
 15VS12    handle=[8,12,15]
 以此类推
 后面的我就不给大家写了直接看下面把
复制代码
let arr = [12, 43, 23, 56, 97, 26];
//1.先抓第一张牌到手里[handle]也需要是个数组用来放抓到的牌
let handle = []; //等于一个空数组用来放抓到的牌;
handle.push(arr[0]); //把数组索引0的一个数放在我们创建的这个数组里;
//2.依次去抓桌面上剩下的牌;
for (let i = 1; i < arr.length; i++) {
    // 因为我们第一项已经拿出来了 所以i从1开始循环 这个地方注意一下;
    let A = arr[i]; //把抓到的牌当作A;
    //3.用每一次抓到的新牌A和手里的牌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
        }
        // 如果和手里的牌都比完了,发现A没有比手里的任何牌大,我们就把A放在最前面即可;
        if (j === 0) {
            handle.unshift(A);
        }
    }
}
console.log(handle);//=>[12, 23, 26, 43, 56, 97]
}

复制代码

再给大家说一个快速排序

11.png

    // 4.结束条件:如果传递的数组小于一项,则无需再拆了
    if (arr.length <= 1) return arr;
    // 1.取出数组中间项
    let middleIndex = Math.round(arr.length / 2),
        middleValue = arr.splice(middleIndex, 1)[0];
    // 2.创建左右两个数组,用原始数组剩下的项和中间项比较,比中间项小的放在左边,大的放在右侧数组中
    let arrLeft = [],
        arrRight = [];
    for (let i = 0; i < arr.length; i++) {
        let item = arr[i];
        item > middleValue ? arrRight.push(item) : arrLeft.push(item);
    }
    // 3.把左边的、中间项、右侧的拼接在一起即可
    return quick(arrLeft).concat(middleValue, quick(arrRight));
};
let arr = [12, 8, 15, 16, 1, 24];
arr = quick(arr);
console.log(arr);
复制代码

对象方法

'XX' in 对象名 : 检测 XX 是否为对象的一个属性。
不能判断是对象公有还是私有的
复制代码

hasOwnProperty //从第二单词开始首字母大写

对象.hasOwnProperty(‘属性’) :检测当前属性是否是对象的私有属性;

给大家分享一个面试题: 检测‘某个属性 attr’ 是否为这个‘对象obj’的‘公有属性’

    // attr in obj:attr是obj的一个属性
    // !obj.hasOwnProperty(attr):attr并不是obj的私有属性
    return (attr in obj) && !obj.hasOwnProperty(attr);
};
console.log(hasPubProperty(f1, 'hasOwnProperty'));
复制代码

这个回答对 但是他是有瑕疵的 :因为如果这个属性它既是公有的也是私有的就没办法检测出来的 所以说它是有瑕疵的

检测是否为公有属性的方案

自己重构:Object.prototype.hasPubProperty 
Object.prototype.hasPubProperty = function hasPubProperty(attr) {
    let proto = Object.getPrototypeOf(this);
    while (proto) {
        // 如果传递的进来的attr是当前找到的proto原型对象中的一个私有属性,则说明attr是实例的一个公有属性
        if (proto.hasOwnProperty(attr)) return true;
        // 只要还可以找到原型对象,则一直向上找
        proto = Object.getPrototypeOf(proto);
    }
    return false;
};
复制代码

创建值两种方案

字面量方案/构造函数方案

对象类型值,基于两种不同方案创造出来的值是没有啥太大区别的。
    obj2 = new Object();
console.log(obj1, obj2); //{} {}
console.log(typeof obj1, typeof obj2); //“object”  “object”
// 对象类型值,基于两种不同方案创造出来的值是没有啥太大区别的 
复制代码

但是对于原始值来讲,两种方案产生的结果是不同的:字面量方案得到的是一个标准的原始值类型值,但是构造函数方案产生的是一个“非标准特殊对象[对象类型的值]”,但是不论哪种方案,创造的都是Number类的一个实例

    n2 = new Number(10);
console.log(n1, n2); //10  {[[PrimitiveValue]]: 10}
console.log(typeof n1, typeof n2); //“number” “object”
复制代码

装箱、拆箱的过程

    n2 = new Number(10);
// n1无键值对,但是n2有{有键值对的是可以进行成员访问操作}
console.log(n2.toFixed(2)); //“10.00”
console.log(n1.toFixed(2)); //“10.00”  
//装箱的过程:浏览器或默认把n1这个原始值类型,隐式转换为new Number(n1)这种对象类型,然后再去调用toFixed方法

console.log(n1 + 10); //20
console.log(n2 + 10); //20  
// 拆箱过程:
// @1 n2[Symbol.toPrimitive] -> undefined
// @2 n2.valueOf() -> 10 
复制代码

原型/原型链(类和实例之间公共属性方法的处理机制)

原型「显式原型」 prototype

原型链「隐式原型」 proto

大部分函数数据类型的值都具备“prototype[原型/显式原型]”属性,属性值本身是一个对象,浏览器会默认为其开辟一个堆内存,用来存储实例和调用的公共属性和方法,在浏览器默认开辟的这个堆内存中(原型对象)有一个默认的属性“constructor(构造函数/构造器)”,属性值是当前函数/类本身;

每一个对象数据类型的值都具备一个属性“proto(原型链/隐式原型)”,属性值指向自己所属类的原型prototype。

原型链机制

访问对象的某个成员,首先看是否为自己私有的,如果是私有的,则直接使用即可;如果不是私有的,默认基于__proto__,找到所属类的prototype,如果找到了,则使用类赋予其的这个公有的属性方法;如果还没有找到,则基于所属类.prototype.__proto__继续向上找…直到找到Object.prototype为止!!!

3333.png

访问到Fn.prototype上的getY方法(上图)

f1.getY();
f1.__proto__.getY(); //  跳过私有的查找【不推荐】:IE中不支持手动访问__proto__
复制代码

这三种方法都可以访问到Fn.prototype上的getY方法,区别是方法执行,里面的this不同。
所有对象都可以访问hsaOwnProperty,是因为每个对象最终都可以基于__proto__原型链查找机制,找到Object.prototype,从而调用hasOwnProperty方法执行。

私有属性:

对象本身存储的属性;

共有属性:

基于__proto__查找到的属性;

属性到底是共有还是私有,需要看相对”谁来讲”

Fn.prototype.hasOwnProperty('getY')    //true  相对Fn。。。
复制代码

谢谢观看

分享到这里能被更多伙伴认可和使用,也是笔者之幸?

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享