Javascript高级进阶

一. 构造函数和原型

1.创建对象的三种方式

1、对象字面量

var obj = {};

2、new Object()

var obj = new Object();

3、new构造函数

function Star(){ }
var ldh = new Star();

2.实例成员和静态成员

1、实例成员就是构造函数内部通过this添加的成员(如下代码中的 name 和 age 是实例成员)

2、静态成员就是在 构造函数本身添加的成员(如下代码中的 sex 是静态成员)

// 构造函数中的属性和方法我们称为成员,成员可以添加
function Star(name, age){
    this.name = name;
    this.age = age;
    this.sing = function(){
       console.log('sing......');
    }
}
// 实例成员(name,age)只能通过实例化的对象来访问,不能通过构造函数访问实例成员
var ldh = new Star('刘德华', 20);
console.log(ldh.name); // 刘德华
console.log(Star.name); // undefined 

// 静态成员只能通过构造函数来访问,不能通过实例化的对象来访问。
Star.sex = '男';
console.log(Star.sex); // 男
console.log(ldh.sex); // undefined

3.构造函数的问题

构造函数存在浪费内存的问题,通过new实例会开辟新的内存空间

function Star(name, age){
    this.name = name;
    this.age = age;
    this.sing = function(){
       console.log('sing......');
    }
}
var ldh = new Star('刘德华', 20);
var zxy= new Star('张学友', 18);
console.log(ldh.sing === zxy.sing); // false 存放的两个不同的内存地址

4.原型对象 prototype

1、原型的概念:是一个对象,通常称prototype为原型对象
2、原型的作用:共享方法
总结:一般情况下,公共的属性定义在构造函数里,公共的方法定义在原型对象上。

function Star(name, age){
    this.name = name;
    this.age = age;
}
Star.prototype.sing = function(){
    console.log('sing......');
}
var ldh = new Star('刘德华', 20);
var zxy= new Star('张学友', 18);
console.log(ldh.sing === zxy.sing); // true 原型对象上存放的是同一个内存地址

5.对象原型 __proto__

通常称__proto__为对象原型。每一个通过new 构造函数构建出来的实例对象都有一个属性为__proto__,它指向着构造函数的原型对象即构造函数的.prototype,所以实例对象可以使用原型对象的属性和方法

function Star(name, age){
    this.name = name;
    this.age = age;
}
Star.prototype.sing = function(){
    console.log('sing......');
}
var ldh = new Star('刘德华', 20);
console.log(ldh.__proto__ === Star.prototype); // true

6. 构造函数 constructor

理解:原型对象(prototype)和对象原型(__proto__)都有一个constructor属性,它指向着构造函数的本身(通俗来说,该实例对象是哪个构造函数构建出来的?)。
作用:1.记录xx实例对象是xx构造函数的引用 2.原型对象利用constructor属性指向构造函数

function Star(name, age) {
    this.name = name;
    this.age = age;
}
/*如果在构造函数原型对象要共享的方法比较多,一般采用对象形式书写.
所以则会把新的对象覆盖掉Star的原型对象,需要手动指回原来的构造函数*/
Star.prototype = {
    constructor: Star,
    sing: function() {
        console.log('sing......');
    },
    dance: function() {
        console.log('dance......');
    }
}
var ldh = new Star('刘德华', 20);
console.log(Star.prototype.constructor); // Star
console.log(ldh.__proto__.constructor); // Star

二. 继承

ES5 继承

<script>
        //es5继承
        //我们创建一个父函数person 让student函数来继承person 

        //创建 Person
        function Person(name, age) {
            this.name = name;
            this.age = age;
        }
        Person.prototype.hello = function () {
            console.log('hello 继承');
        }

        //创建 Student 让他继承 Person 
        function Student(name, age, sid) {
            //下面是继承属性的过程
            //首先 name和age属性我希望可以通过Person继承得到
            //我们可以通过函数的调用来实现Person的复用
            //    Person(name,age)
            //但上面的写法,在Person中的this 就会指向 window 而window是没有这两个属性的
            //所以我们可以强行改变Person函数中this的指向  可以通过 call apply bind方法中的随意一个
            //这里我们用call  call的用法为 call(要this指向的对象,参数1,参数2);
            Person.call(this, name, age); //这里在this为 Student
            this.sid = sid;
        }

        //下面是继承方法的过程
        //首先我们知道Person的方法是存放在prototype上面的 那么我们要做的就是,将Student的prototype 指向Person的prototype就可以了
        //   Student.prototype=Person.prototype;
        //但这种方式会出现一个问题,就是在给Student添加方法的话,就会直接添加到Person上
        //所以我们可以创建一个空元素,让他的__proto__指向Person的prototype
        let tmp = Object.create(Person.prototype);
        // Object.create(对象A) 返回一个空对象 其__proto__指向对象A的prototype
        //然后将 Student的prototype 指向空对象的__proto__
        Student.prototype = tmp;
        //如果子类的方法与父类方法同名,想要执行父类的方法,子类的方法要在继承之后写
        Student.prototype.hello = function () {
            console.log('hello 继承!!!')
        }
        let p = new Person('xiaoxiao', 6);
        console.log(p.name, '-', p.age);
        p.hello();
        let s = new Student('xiaoming', 18, '1653');
        console.log(s.name, '-', s.sid);
        s.hello();
    </script>

 
 ES6 继承

 <script>
        //es6的继承是通过extends实现的
        //同样我们创建一个父函数Person,让Student来继承
        //创建Person
        class Person {
                constructor(name, age) {
                    this.age = age;
                    this.name = name;
                }
                hello() {
                    console.log('hello world')
                }
            }

            //创建 Student
            class Student extends Person {
                constructor(name, age, sid) {
                    //es6的属性与方法继承,通过super 
                    super(name, age);
                    this.sid = sid;
                }
                //如果想执行student自己的hello方法
                hello() {
                    console.log('hello node.js')
                }
            }
            let p = new Person('xiaoxiao', 6);
            console.log(p.name, '-', p.age);
            p.hello();
            
            let s = new Student('xiaoming', 18, '1653');
            console.log(s.name, '-', s.sid);
            s.hello();
 </script>


 

三. 常用方法

1. 数组方法

  • foreach() 循环遍历数组,没有返回值
    参数:value为数组中的每一项,index为每一项的索引值,arr则为数组的本身, 。
var arr = [1,2,3,4];
arr.foreach((item,index,arr) => {
     console.log('当前项:', item); // 1,2,3,4
     console.log('当前项索引值:', index); // 0,1,2,3
     console.log('数组:', arr); // 输出4次 [1,2,3,4]
})

  • map() 创建一个的新数组并返回,不影响原数组。:
var arr = [1, 2, 3, 4];
var newArr = arr.map((item, index) => item % 2 === 0));
console.log(newArr); // [2,4]

  • filter() 一般用于数组过滤,符合条件的元素组成新的数组并返回,没有符合条件则返回空数组。不影响原数组。
var arr = [10, 20, 30, 40];
var newArr = arr.filter((item, index, arr) => item > 20);
console.log(newArr); // [30, 40]

  • some() 用于查找数组中符合条件的元素,如果任意一项符合条件则返回,会终止循环,不再继续往下执行,一项符合条件返回true, 否则返回false
    *注意:空数组返回false
var arr = [10, 20, 30, 40, 50];
var flag = arr.some((item, index) => item > 100);
console.log(flag); // false
console.log([].some(item => item)); // false

  • every()

用于查找数组中符合条件的元素,如果每一项都符合条件则返回true, 否则返回false
*注意:空数组返回true

var arr = [10, 20, 30, 40, 50];
var flag = arr.every((item, index) => item > 5);
console.log(flag); // true
console.log([].every(item => item)); // true

2. 字符串方法

  • trim() 用于去除字符串首尾空格,并返回去掉空格后的字符串。
var str= ' abc ';
var newStr = str.trim();
console.log(newStr); // abc

3.对象方法

  • Object.keys() 用于获取对象自身所有的属性(类似于for...in)并返回由属性名组成的数组
var obj = {
    name: 'tao',
    age: 18
}
var arr = Object.keys(obj);
console.log(arr); // ['name', 'age']

​​​​​​​

  • Object.defineProperty() 用于定义新属性或修改原有的属性

Object.defineProperty(obj, prop, descriptor)
obj 需要定义属性的当前对象
prop 当前需要定义的属性
descriptor 属性描述符。

var obj = {};
// 用defineProperty定义和修改属性
Object.defineProperty(obj, 'name', {
    value: 'tao',
    enumerable: false, // 是否可遍历 默认false
    writable: false, // 是否可重写 默认false
    configureable: false // configurable属性性表示对象的属性是否可以被删除,以及除writable属性外的其他属性是否可以被修改。
})
console.log(obj);
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值