【小白鲨笔记】js面试题(五)

18 篇文章 0 订阅

五、Js对象

  1. 对象为引用数据类型:若是直接赋值,相当于赋值该对象的地址

  2. 对象是通过new构造出来的,彼此之间都是不一样的

  3. 对象的key都是字符串类型

  4. 如何查找属性/方法:

    • 每一个将函数自带一个原型(prototype
    • 每一个对象拥有一个对象原型(__proto__)
    • new 对象:该对象构造函数的原型指向对象的原型
    function fn() {}
    let obj = new fn()
    console.log(fn.prototype === obj.__proto__)
    
    • 查找顺序:原型链
      1. 对象本身
      2. 构造函数
      3. 对象原型
      4. 构造函数原型
      5. 对象上一层原型
    function fn(){ this.a = 'this.a' } // 2
    fn.prototype.a = 'prototype.a' // 4
    let obj = new fn()
    obj.a = 'obj.a' // 1
    obj.__proto__.a = '__proto__.a' // 3
    Object.prototype.a = 'Object.prototype.a' // 5
    console.log(obj.a) // 顺序:obj、this、__proto__、prototype、Object
    
考题1:
var o = { b: 'bb' }
var obj = { a:1, 'zs': 'hey' }
obj[o] = '123' // obj = { a:1, 'zs': 'hey', [object Object] = '123' }
for (var k in obj) {
    console.log(typeof k) // string
}
考题2:
var a = {}
var b = { k: 'b' }
var c = { k: 'c' }
a[b] = '123' // b将被转为字符串[object Object]
a[c] = '456' // c转为字符串并覆盖b,c与b都属于同一个key:[object Object]
console.log(a[b]) // 456

1、this指向

  1. 普通函数
    • 普通函数:this指向window

      function A() {console.log(this)} //window
      
    • 普通函数闭包:this指向window

      function A() { return function(){ console.log(this) }} //window
      
考题1:
  1. 返回什么?

  2. 是否执行函数体中的代码?

function fn(){
    console.log('111')
    console.log(this)
    return 'aaa'
}
console.log(fn) // 打印函数体:function fn(){} -- 未执行
console.log(fn()) // 返回对象 -- 执行:this = window
console.log(new fn()) // 新对象fn{} -- 执行:this = fn{}
考题2:
// 声明:
function foo(){
    getName = function(){ console.log(1) } // 全局window
    return this
}
foo.getName = function(){ console.log(2) }
foo.prototype.getName = function(){ console.log(3) }
var getName = function() { console.log(4) }
function getName() { console.log(5) }
// 执行:
foo.getName() // 2 -- foo函数未执行,直接查找函数本身
getName() // 4 -- getName声明大于函数,若是变量提升就该输出5
foo().getName() //1 -- 执行foo函数,等于将this = window返回,相当于window.getName()
getName() // 1 -- 上一行的getName变成全局覆盖
new foo.getName() // 2 -- 根据对象原型链去查找(先看对象本身,再找原型),在foo函数中的getName是window的所以不采用
考题3:
var o = {
    a: 10,
    b: {
        // a: 1, -- 若添加此行,下面的this.a = 1
        fn: function(){
            console.log(this) // b
            console.log(this.a) // b.a = undefined
        }
    }
}
o.b.fn() // undefined
考题4:
name = 'ByteDance'
function A() { this.name = 123 }
A.prototype.getA = function () {
  console.log(this)
  return this.name + 1
}
let a = new A() // 对象
let fnA = a.getA // 未执行:this = window
console.log(fnA()) // ByteDance1
let fnB = a.getA() // 执行:this = a(A{name: 123})
console.log(fnB) // 124
考题5:
var len = 10
function fn(){ return this.len + 1 }
var obj = { len: 5, test1: function(){ return fn() } } // 执行:this指向window
obj.test2 = fn // 未执行 -- 相当于:obj.test2 = function(){return this.len+1}
console.log(obj.test1()) // 11
console.log(fn() === obj.test2()) // false:test2的this指向obj,而fn指向window
console.log(obj.test1() == obj.test2()) // false:同理

2、原型链

  1. 原型能解决的问题:对象共享属性、方法(继承机制)

    • new 构造函数:而构造函数不能共享属性、方法,因此需要用到prototype

    注意:js中new后面不是类名,而是构造函数

  2. 原型存在体:

    • 函数原型(显式):prototype

    • 对象原型(隐式):__proto__

    proto 对比 prototype:proto是每个实例都有的属性(实例没有prototype),可以访问构造函数的prototype属性(proto与prototype指向的是同一个对象)

    function Fn() {}
    console.log(Fn().prototype) //{constructor:f}
    console.log(new Fn().prototype) //undefined
    console.log(new Fn().__proto__) //{constructor:f}
    
  3. 原型链:原型都连接起来,原型链的最顶端是null

    原型链中对象查找属性/方法顺序:

    1. 对象本身查找

    2. 构造函数中查找

    3. 对象的原型

    4. 构造函数的原型中

    5. 当前原型的原型中查找

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值