JavaScript原型

1.提出原型

创建对象的构造函数方法:

    <script>
        function Person(name,age,gender){
            this.name = name;
            this.age = age;
            this.gender = gender;
            this.say = function(content){
                console.log(content);
            }
        }
        var p1 = new Person("tom",4,"male");
        var p2 = new Person("jerry",3,"male");
        console.log(p1);
        console.log(p2);
        console.log(p1.say === p2.say);
    </script>

p1和p2指向的不是同一个函数体,调用多次会非常复杂。

解决方法是把函数抽取到外面。

    <script>
        function Person(name,age,gender){
            this.name = name;
            this.age = age;
            this.gender = gender;
            this.say = fn;
            }
        function fn(content){
            console.log(content);
        }
        var p1 = new Person("tom",4,"male");
        var p2 = new Person("jerry",3,"male");
        console.log(p1.say === p2.say);
    </script>

但是,fn是全局函数,会造成全局污染,可以用原型解决。

2.关键点

每一个函数在定义的时候,都会有跟它关联的一个对象被创建出来。

每一个由构造函数创建出来的对象,都会默认的和构造函数的神秘对象关联。

当使用一个方法进行属性或者方法访问的时候,会先在当前对象内查找该属性和方法。

如果当前对象未找到,就回去跟它关联的神秘对象内进行查找。

获取神秘对象:构造函数的名字.prototype

    <script>
        function Person(name,age,gender){
            this.name = name;
            this.age = age;
            this.gender = gender;
            this.say = function(content){
                console.log(content);
            }
        }
        Person.prototype.sayHi = function(){
            console.log("hi......");
        }
        var p1 = new Person("tom",4,"male");
        var p2 = new Person("jerry",3,"male");
        p1.sayHi();
        console.log(p1.say === p2.say);
        console.log(p1.sayHi === p2.sayHi);
    </script>

 3.原型属性和查找方法

    <script>
        function Person(){};
        Person.prototype.name = "tom";
        var p1 = new Person();
        console.log(p1.name);
    </script>

    <script>
        function Person(){};
        Person.prototype.name = "tom";
        var p1 = new Person();
        p1.name = "jerry";
        console.log(p1.name);
    </script>

在访问的时候,如果没有该属性就到构造函数的原型中找

    <script>
        function Person(){
            this.say = function(){
                console.log("构造函数中的say");
            }
        }
        Person.prototype.say = function(){
            console.log("原型中的say");
        }
        var p1 = new Person();
        p1.say();
    </script>

 

 4.原型的使用

    <script>
        function Person(){};
        Person.prototype.say = function(){
            console.log("say hello!");
        }
        console.log(Person.prototype);
        var obj = {
            say:function(){
                console.log("hello!");
            },
            sayHi:function(){
                console.log("hi!hi!");
            }
        }
        Person.prototype = obj;
        console.log(Person.prototype);
    </script>

 对比两次输出的Person.prototype,不同点在于constructor(告诉当前的原型是属于哪一个构造的)

手动维护,如果将构造函数的原型替换为其他对象的话,一定要加上constructor属性指明当前原型的构造是谁

Person.prototype.constuctor = obj;

 

 或者把后来定义的say,sayHi添加到原型上。

    <script>
        function Person(){};
        Person.prototype.say = function(){
            console.log("say hello!");
        }
        console.log(Person.prototype);
        var obj = {
            say:function(){
                console.log("hello!");
            },
            sayHi:function(){
                console.log("hi!hi!");
            }
        }
        for(var k in obj){
            Person.prototype[k] = obj[k];
        }
        console.log(Person.prototype);
    </script>

 

 然后调用say方法

var p = new Person();
p.say();

后面的say方法把前面的覆盖掉了。

5.原型继承

 如果想继承另一个对象里的方法,(举的例子是obj)那么就要写很多遍for in,所以,可以创建一个方法,把要继承的对象传进去,然后调用这个方法。

    <script>
        var Animal = {
            name:"qq",
            age:5,
            gender:"male",
            say:function(){
                console.log("wang!");
            }
        }
        function Dog(){
            this.color = "black";
        }
        Dog.prototype.extend = function(obj){
            for(var k in obj){
                this[k] = obj[k];
            }
        }
        Dog.prototype.extend(Animal);
        console.log(Dog.prototype);
    </script>

 6.原型链

实例对象 -> 构造函数.原型 -> 原型的原型 -> ... -> Object.prototype -> undefined | xxx is not a function

        function Animal(){
            this.name = "animal",
            this.say = function(){
                console.log("Animal is animal");
            }
        }
        Person.prototype = new Animal();
        Person.prototype.constructor = Person;
        function Person(){
            this.name = "person",
            this.say = function(){
                console.log("Person is person");
            }
        }
        Student.prototype = new Person();
        Student.prototype.constructor = Student;
        function Student(){
            this.name = "student",
            this.say = function(){
                console.log("Student is a student");
            }
        }
        Teacher.prototype = new Student();
        Teacher.prototype.constructor = Teacher;
        function Teacher(){
            this.name = "teacher",
            this.say = function(){
                console.log("Teacher is a teacher");
            }
        }
        console.log(Teacher.prototype);

 7.Object

console.log(Object.prototype);

看一下Object的原型了解这几个方法。

1.hasOwnProperty 判断对象本身(不包括原型)是否拥有某个属性。

    <script>
        function Person(){
            this.name = "lucy",
            this.age = 19,
            this.say = function(){
                console.log("I'm Lucy.");
            }
        }
        Person.prototype.gender = "female";
        var p = new Person();
        console.log(p.hasOwnProperty("name"));
        console.log(p.hasOwnProperty("gender"));
    </script>

 

 2.propertyIsEnumerable 判断属性是否属于对象本身,判断属性是否可以遍历

Object.defineProperty 添加某个属性的时候可以附加一些信息

    <script>
        function Person(){
            this.name = "lucy",
            this.age = 19,
            this.say = function(){
                console.log("I'm Lucy.");
            }
        }
        Person.prototype.gender = "female";
        var p = new Person();
        Object.defineProperty(p,"name",{
            value:"tom",
            //控制当前属性是否能被遍历
            enumerable:false,
            //是否可以写
            writable:false,
            //控制当前属性是否可以被删除
            configurable:false
        })
        console.log(p.propertyIsEnumerable("name"));
        console.log(p.propertyIsEnumerable("gender"));
    </script>

 set,get方法

    <script>
        function Person(){
            this.name = "lucy",
            this.age = 19,
            this.say = function(){
                console.log("I'm Lucy.");
            }
        }
        Person.prototype.gender = "female";
        var p = new Person();
        Object.defineProperty(p,"age",{
            get:function(){
                console.log("在获取age属性的时候会自动调用此方法");
                try {
                    return initValue;
                } catch (error) {
                    return undefined
                }
            },
            set:function(value){
                if(value < 0 || value > 130){
                    console.log("年纪不符合逻辑");
                    return initValue = "超岁数了";
                }
                initValue = value;
            }
        })
        p.age = -14;
        console.log(p.age);
    </script>

 p.age = 14;
 console.log(p.age);

 

 8.举例

1.

请补全JavaScript代码,实现以下功能:
1. 给"Human"构造函数的原型对象添加"getName"方法,返回当前实例"name"属性
2. 将"Chinese"构造函数继承于"Human"构造函数
3. 给"Chinese"构造函数的原型对象添加"getAge"方法,返回当前实例"age"属性

        <script type="text/javascript">
            function Human(name) {
                this.name = name
                this.kingdom = 'animal'
                this.color = ['yellow', 'white', 'brown', 'black']
            }
            function Chinese(name,age) {
                Human.call(this,name)
                this.age = age
                this.color = 'yellow'
            }

            // 补全代码
            Human.prototype.getName = function(){
                return this.name;
            }
            Chinese.prototype = new Human();
            Chinese.prototype.constructor = Chinese;
            Chinese.prototype.getAge = function(){
                return this.age;
            }
        </script>

2.

请补全JavaScript代码,要求在Number对象的原型对象上添加"_isPrime"函数,该函数判断调用的对象是否为一个质数,是则返回true,否则返回false。

        <script type="text/javascript">
        	// 补全代码
        	Number.prototype._isPrime = function(num){
                for(let i = 2; i < num; i++){
                    if(num % i == 0){
                        return false
                    }   
                }
                return true
            }
        </script>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值