JavaScript高级——构造函数创建对象

1.构造对象

// 1. 利用 new Object() 创建对象
var obj1 = new Object();
// 2. 利用 对象字面量创建对象
var obj2 = {};
// 3. 利用构造函数创建对象
function Star(uname, age) {
this.uname = uname;
this.age = age;
this.sing = function() {
console.log(‘我会唱歌’);
}
}
var ldh = new Star(‘刘德华’, 18);
var zxy = new Star(‘张学友’, 19);
console.log(ldh);
ldh.sing();
zxy.sing();

2.静态对象和实例化对象

  // 构造函数中的属性和方法我们称为成员, 成员可以添加
    function Star(uname, age) {
        this.uname = uname;
        this.age = age;
        this.sing = function() {
            console.log('我会唱歌');

        }
    }
    var ldh = new Star('刘德华', 18);
    // 1.实例成员就是构造函数内部通过this添加的成员 uname age sing 就是实例成员
    // 实例成员只能通过实例化的对象来访问
    console.log(ldh.uname);
    ldh.sing();
    // console.log(Star.uname); // 不可以通过构造函数来访问实例成员
    // 2. 静态成员 在构造函数本身上添加的成员  sex 就是静态成员
    Star.sex = '男';
    // 静态成员只能通过构造函数来访问
    console.log(Star.sex);
    console.log(ldh.sex); // 不能通过对象来访问

3.对象原型prototype.

// 1. 构造函数的问题.
function Star(uname, age) {
this.uname = uname;
this.age = age;
}
Star.prototype.sing = function() {
console.log(‘我会唱歌’);
}
var ldh = new Star(‘刘德华’, 18);
var zxy = new Star(‘张学友’, 19);
console.log(ldh.sing === zxy.sing);
// console.dir(Star);
ldh.sing();
zxy.sing();
// 2. 一般情况下,我们的公共属性定义到构造函数里面, 公共的方法我们放到原型对象身上

4.给原型对象添加多个新的方法要是有constructor构造指回原来的构造函数

Star.prototype = {
// 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数
constructor: Star,
sing: function() {
console.log(‘我会唱歌’);
},
movie: function() {
console.log(‘我会演电影’);
}
}

6. call 方法,可以调用函数,可以改变这个函数的this指向 此时这个函数的this 就指向了o这个对象

    function fn(x, y) {
        console.log('我想喝手磨咖啡');
        console.log(this);
        console.log(x + y);
    }
    var o = {
        name: 'andy'
    };
 	 fn.call();
    fn.call(o, 1, 2);

7. 借用父构造函数继承属性

    // 1. 父构造函数
    function Father(uname, age) {
        // this 指向父构造函数的对象实例
        this.uname = uname;
        this.age = age;
    }
    // 2 .子构造函数 
    function Son(uname, age, score) {
        // this 指向子构造函数的对象实例
        Father.call(this, uname, age);
        this.score = score;
    }
    var son = new Son('刘德华', 18, 100);
    console.log(son);

8.forEach 迭代(遍历) 数组

    var arr = [1, 2, 3];
    var sum = 0;
    arr.forEach(function(value, index, array) {
        console.log('每个数组元素' + value);
        console.log('每个数组元素的索引号' + index);
        console.log('数组本身' + array);
        sum += value;
    })
    console.log(sum);

9. filter 筛选数组 查询卡价格

    var arr = [12, 66, 4, 88, 3, 7];
    var newArr = arr.filter(function(value, index) {
        // return value >= 20;
        return value % 2 === 0;
    });
    console.log(newArr);

10. some 查找数组中是否有满足条件的元素 查询属性值唯一的可使用some节省时间

	var arr1 = ['red', 'pink', 'blue'];
    var flag1 = arr1.some(function(value) {
        return value == 'pink';
    });
    console.log(flag1);
    // 1. filter 也是查找满足条件的元素 返回的是一个数组 而且是把所有满足条件的元素返回回来
    // 2. some 也是查找满足条件的元素是否存在  返回的是一个布尔值 如果查找到第一个满足条件的元素就终止循环

11 Object.keys(obj)用于获取对象自身所有的属性

    var obj = {
        id: 1,
        pname: '小米',
        price: 1999,
        num: 2000
    };
    var arr = Object.keys(obj);
    console.log(arr);
    arr.forEach(function(value) {
        console.log(value);
    })

12 .Object.defineProperty() 定义新属性或修改原有的属性enumerable是否允许遍历 writable 是否允许可改configurable 是否隐藏该属性

    var obj = {
        id: 1,
        pname: '小米',
        price: 1999
    };
Object.defineProperty(obj, 'address', {
        value: '中国山东蓝翔技校xx单元',
        // 如果只为false 不允许修改这个属性值 默认值也是false
        writable: false,
        // enumerable 如果值为false 则不允许遍历, 默认的值是 false
        enumerable: false,
        // configurable 如果为false 则不允许删除这个属性 不允许在修改第三个参数里面的特性 默认为false
        configurable: false
    });

13. 函数的定义方式

 1. 自定义函数(命名函数) 
        function fn() {};
2. 函数表达式 (匿名函数)
        var fun = function() {};
 3. 利用 new Function('参数1','参数2', '函数体');
        var f = new Function('a', 'b', 'console.log(a + b)');
        f(1, 2);
4. 所有函数都是 Function 的实例(对象)
        console.dir(f);
5. 函数也属于对象
        console.log(f instanceof Object);

14 函数的调用方式

    // 1. 普通函数
    function fn() {
        console.log('人生的巅峰');
    }
    // fn();   fn.call()
    // 2. 对象的方法
    var o = {
        sayHi: function() {
            console.log('人生的巅峰');
        }
    }
    o.sayHi();
    // 3. 构造函数
    function Star() {};
    new Star();
    // 4. 绑定事件函数
    // btn.onclick = function() {};   // 点击了按钮就可以调用这个函数
    // 5. 定时器函数
    // setInterval(function() {}, 1000);  这个函数是定时器自动1秒钟调用一次
    // 6. 立即执行函数
    (function() {
        console.log('人生的巅峰');
    })();
    // 立即执行函数是自动调用

14. 函数的不同调用方式决定了this 的指向不同

 // 1. 普通函数 this 指向window
    function fn() {
        console.log('普通函数的this' + this);
    }
    window.fn();
// 2. 对象的方法 this指向的是对象 o
    var o = {
        sayHi: function() {
            console.log('对象方法的this:' + this);
        }
    }
    o.sayHi();
    // 3. 构造函数 this 指向 ldh 这个实例对象 原型对象里面的this 指向的也是 ldh这个实例对象
    function Star() {};
    Star.prototype.sing = function() {

    }
    var ldh = new Star();
    // 4. 绑定事件函数 this 指向的是函数的调用者 btn这个按钮对象
    var btn = document.querySelector('button');
    btn.onclick = function() {
        console.log('绑定时间函数的this:' + this);
    };
    // 5. 定时器函数 this 指向的也是window
    window.setTimeout(function() {
        console.log('定时器的this:' + this);

    }, 1000);
    // 6. 立即执行函数 this还是指向window
    (function() {
        console.log('立即执行函数的this' + this);
    })();

15 改变函数this指向 call apply bind

 1. call()
    var o = {
        name: 'andy'
    }
    function fn(a, b) {
        console.log(this);
        console.log(a + b);
    };
    fn.call(o, 1, 2);
    // call 第一个可以调用函数 第二个可以改变函数内的this 指向
    // call 的主要作用可以实现继承
    function Father(uname, age, sex) {
        this.uname = uname;
        this.age = age;
        this.sex = sex;
    }
    function Son(uname, age, sex) {
    //不在使用extends继承
        Father.call(this, uname, age, sex);
    }
    var son = new Son('刘德华', 18, '男');
    console.log(son);
2. apply()  应用 运用的意思
    var o = {
        name: 'andy'
    };
    function fn(arr) {
        console.log(this);
        console.log(arr); // 'pink'
    };
    fn.apply(o, ['pink']);
    // 1. 也是调用函数 第二个可以改变函数内部的this指向
    // 2. 但是他的参数必须是数组(伪数组)
    // 3. apply 的主要应用 比如说我们可以利用 apply 借助于数学内置对象求数组最大值 
    // Math.max();
    var arr = [1, 66, 3, 99, 4];
    var arr1 = ['red', 'pink'];
    // var max = Math.max.apply(null, arr);
    var max = Math.max.apply(Math, arr);
    var min = Math.min.apply(Math, arr);
    console.log(max, min);
    3.  bind()  绑定 捆绑的意思
    <button>点击</button>
    <button>点击</button>
    <button>点击</button>
    // 1. 不会调用原来的函数   可以改变原来函数内部的this 指向
    // 2. 返回的是原函数改变this之后产生的新函数
    // 3. 如果有的函数我们不需要立即调用,但是又想改变这个函数内部的this指向此时用bind
    // 4. 我们有一个按钮,当我们点击了之后,就禁用这个按钮,3秒钟之后开启这个按钮
    // var btn1 = document.querySelector('button');
    // btn1.onclick = function() {
    //     this.disabled = true; // 这个this 指向的是 btn 这个按钮
    //     // var that = this;
    //     setTimeout(function() {
    //         // that.disabled = false; // 定时器函数里面的this 指向的是window
    //         this.disabled = false; // 此时定时器函数里面的this 指向的是btn
    //     }.bind(this), 3000); // 这个this 指向的是btn 这个对象
    // }

16闭包(closure)指有权访问另一个函数作用域中变量的函数。

    // 闭包: 我们fun 这个函数作用域 访问了另外一个函数 fn 里面的局部变量 num
    function fn() {
        var num = 10;
        function fun() {
            console.log(num);
        }
        fun();
    }
    fn();

17 浅拷贝与深拷贝

浅拷贝是拷贝地址,修改值会影响原数组
深拷贝是自建地址来存储,不会影响原数据
// 浅拷贝只是拷贝一层, 更深层次对象级别的只拷贝引用.
// 深拷贝拷贝多层, 每一级别的数据都会拷贝.
    var obj = {
        id: 1,
        name: 'andy',
        msg: {
            age: 18
        }
    };
    var o = {};
    // for (var k in obj) {
    //     // k 是属性名   obj[k] 属性值
    //     o[k] = obj[k];
    // }
    // console.log(o);
    // o.msg.age = 20;
    // console.log(obj);
    console.log('--------------');
    Object.assign(o, obj);
	 console.log(o);

18 深拷贝拷贝多层, 每一级别的数据都会拷贝.

    var obj = {
        id: 1,
        name: 'andy',
        msg: {
            age: 18
        },
        color: ['pink', 'red']
    };
    var o = {};
    // 封装函数 
    function deepCopy(newobj, oldobj) {
        for (var k in oldobj) {
            // 判断我们的属性值属于那种数据类型
            // 1. 获取属性值  oldobj[k]
            var item = oldobj[k];
            // 2. 判断这个值是否是数组
            if (item instanceof Array) {
                newobj[k] = [];
                deepCopy(newobj[k], item)
            } else if (item instanceof Object) {
                // 3. 判断这个值是否是对象
                newobj[k] = {};
                deepCopy(newobj[k], item)
            } else {
                // 4. 属于简单数据类型
                newobj[k] = item;
            }
        }
    }
    deepCopy(o, obj);
    console.log(o);
    var arr = [];
    console.log(arr instanceof Object);
    o.msg.age = 20;
    console.log(obj);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值