前端面试之原型、class以及数据类型判断

一,函数对象

            所有引用类型(函数,数组,对象)都拥有__proto__属性(隐式原型)

            所有函数拥有prototype属性(显式原型)(仅限函数)

            原型对象:拥有prototype属性的对象,在定义函数时就被创建

二、构造函数

//创建构造函数
        function Word(words){
            this.words = words;
        }
        Word.prototype = {
            alert(){
                alert(this.words);
            }
        }
        //创建实例
        var w = new Word("hello world");
        w.print = function(){
            console.log(this.words);
            console.log(this);  //Person对象
        }
        w.print();  //hello world
        w.alert();  //hello world

当调用某种方法或查找某种属性时,首先会在自身调用和查找,如果自身并没有该属性或方法,则会去它的__proto__属性中调用查找,也就是它构造函数的prototype中调用查找

三、原型

①所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象
②所有函数都有一个prototype(原型)属性,属性值是一个普通的对象
③所有引用类型的__proto__属性指向它构造函数的prototype

var a = [1,2,3];
a.__proto__ === Array.prototype; // true

四、原型链

当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。

举例,有以下代码

function Parent(month){
    this.month = month;
}

var child = new Parent('Ann');

console.log(child.month); // Ann

console.log(child.father); // undefined

五、构造函数、对象实例、原型对象三者之间的关系

1.构造函数可以实例化对象
2.构造函数中有一个属性叫prototype,是构造函数的原型对象
3.构造函数的原型对象(prototype)中有一个constructor构造器,这个构造器指向的就是自己所在的原型对象所在的构造函数
4. 实例对象的原型对象(proto)指向的是该构造函数的原型对象
5.构造函数的原型对象(prototype)中的方法是可以被实例对象直接访问的
在这里插入图片描述

  1. 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性
  2. 如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)
  3. 如果还没有就查找原型对象的原型(Object的原型对象)
  4. 依此类推一直找到 Object 为止(null)
  5. __proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线

六、类class

class Dog():
    """ very first try """

    def __init__(self, name, age,):
        """initiate name and age"""
        self.name = name
        self.age = age

    def sit(self):
        print(self.name.title() + " is now sitting")

    def roll_over(self):
        print(self.name.title() + " rolled over!")

首字母大写名称指的是类,其中Dog()中的()是空的,因为是从空白创建这个类 类中的函数称为 方法,
对于__init__(特定),开头结尾各俩下划线,每次根据Dog创造新的实例的时候就会自动运行 其中定义的三个实参,self, name
,age。 self是必不可少且必须位于最前的。 当调用__init__创建Dog实例时,将自动传入实参self,不需要传递值。
每个与类相关联的方法调用都自动传递实参self,是指向实例本身的引用
以self为前缀的变量可以供类中的所有方法使用,可以通过类的任何实例来访问变量。 self.name = name
获取存储在形参name中的值,并将其存储在变量name中,然后该变量name被关联到当前创建的实例中。
可以通过实例访问的变量(name,age)称为属性。
根据类创建实例
class Dog()后

my_dog = Dog('Lucas', 6)
print("my dog's name is " + my_dog.name + ".")
print("my dog is " + str(my_dog.age) + ".")

当传递实参时,调用了Dog类中的方法__init__(),方法__init__创建了一个表示特定小狗的示例。方法__init__并未显式包含return语句,但自动返回一个表示这条狗的实例。利用变量my_dog储存这个实例。

首字母大写的名称Dog表示类
小写的名称my_dog指的是根据类创建的实例

访问属性用句点表示法即可,my_dog.name

默认值
类中的每个属性都必须有初始值,哪怕这个值是0或者空字符串。在方法__init__()内指定这种初始值时,无需包含为它提供初始值的形参。

class Car:

    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer = 0

    def descriptive_name(self):
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()

    def miles(self):
        print('this car has ' + str(self.odometer) + " miles on it. ")


my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.descriptive_name())
my_new_car.miles()
>
>2016 Audi A4
this car has 0 miles on it. 

继承
创建子类时,最首先的任务是给父类所有属性赋值。子类的方法__init__需要父类施以援手?????
电动汽车属于汽车,故以电动汽车作为子类,这样就只需为电动汽车特有的属性和行为编码。

class Car:

    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer = 0

    def descriptive_name(self):
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()

    def update_odometer(self, mileage):
        """set the reading to referred value"""
        self.odometer = mileage

    def miles(self):
        print('this car has ' + str(self.odometer) + " miles on it. ")


class ElectricCar(Car):
    def __init__(self, make, model, year):
    “”“初始化父类的属性”“”
        super().__init__(make, model, year)


my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.descriptive_name())

注意:
1.创建子类时,父类必须包含在当前文件中,且位于子类前面。
2.定义子类时,必须在括号内指定父类的名称,方法__init__必须接受创建Car实例所需的信息

class ElectricCar(Car):

3.super()是一个特殊函数,将父类和子类联系起来

super().__init__(make, model, year)

这行代码调用父类方法__init__(),让Electricity实例包含父类的所有属性
4.

class ElectricCar(Car):
    def __init__(self, make, model, year):
    “”“初始化父类的属性”“”
        super().__init__(make, model, year)


my_tesla = ElectricCar('tesla', 'model s', 2016)

创建一个E car的实例,并将其储存在变量my_tesla中,调用E Car类中定义的方法__init__(),init()可调用Car中定义的方法__init__()

七、JavaScript 中常见的几种数据类型:

基本类型:string,number,boolean

特殊类型:undefined,null

引用类型:Object,Function,Function,Array,Date,…

typeof

typeof 返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、object、undefined、function等6种数据类型。如果是判断一个基本的类型用typeof就是可以的。

typeof ''; // string 有效
typeof 1; // number 有效
typeof true; //boolean 有效
typeof undefined; //undefined 有效
typeof null; //object 无效
typeof [] ; //object 无效
typeof new Function(); // function 有效
typeof new Date(); //object 无效
typeof new RegExp(); //object 无效

typeof 可以对JS基础数据类型做出准确的判断,而对于引用类型返回的基本上都是object, 其实返回object也没有错,因为所有对象的原型链最终都指向了Object,Object是所有对象的祖宗。 如果判断的是引用类型的话,typeof 就显得有些力不从心了。

instanceof

instanceof 是用来判断 A 是否为 B 的实例对,表达式为:A instanceof B,如果A是B的实例,则返回true,否则返回false。 在这里需要特别注意的是:instanceof检测的是原型,

[] instanceof Array; //true
{} instanceof Object;//true
new Date() instanceof Date;//true
Object.prototype.toString 

toString是Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,更严格的讲,是 toString运行时this指向的对象类型, 返回的类型格式为[object,xxx],xxx是具体的数据类型,其中包括:String,Number,Boolean,Undefined,Null,Function,Date,Array,RegExp,Error,HTMLDocument,… 基本上所有对象的类型都可以通过这个方法获取到。

Object.prototype.toString.call('') ;   // [object String]
Object.prototype.toString.call(1) ;    // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只小 Ziyi.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值