review,constructor,instanceof,in

本文探讨了JavaScript中的单例模式实现,包括使用对象字面量、高级单例函数和工厂模式的区别,以及构造函数、原型模式的应用。同时讲解了`instanceof`、`in`和`hasOwnProperty`等概念,以及如何操作对象的私有属性和原型链。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

review

// 单例模式 命名空间

let zhangsan = {

name:" "

}

// 高级单例 用一个函数返回一个对象

let lisi = (function () {

let count = 100

return {

add() {

console.log(count++)

}

}

})()

let home = (function () {

})()

// 工厂模式

function factory(name, age, flag = false) {

if (flag) {

name = name + 'AAA'

}

return {

name,

age

}

}

let p1 = factory("张家界", 100, true)

let p2 = factory("香山", 100)

// 构造函数模式

function Person(name, age) {

this.name = name;

this.age = age;

}

letp3 = newPerson('账单', 123)

// 原型模式

function Student(name, age) {

this.name = name;

this.age = age;

}

// Student这个类的原型上存放的 属性,都是供 Student的实例去使用的公用属性

Student.prototype.study = function () {

// study这个方法 是Student的实例能有调用

}

let p4 = newStudent('账单', 123)

/*

new 执行的过程:

先开作用域, 开一个堆内存,让函数中的this指向这个堆;

然后 形参赋值 变量提升;

然后代码从上到下执行;

return的问题

return 后边跟一个引用类型 则返回的就是写的这个引用类型

否则返回时这个堆内存(this-->实例)

*/

/*

this 箭头函数的this去上级作用域查找;

事件绑定 this就是绑定的元素

自执行 和 定时器对应的回调函数 中的this 是window;

全局下的this是window

看点 点前边是谁 this就是谁 (this 函数的执行主体);没点就是window

严格模式 "use strict" 不指定就是undefined

*/

/*

函数都有prototype,里边用来存储实力能够使用的公用属性

自带的(默认的)的prototype上都有 constructor ; 指的是 这个构造函数本身

所有的实例 都有一个__proto__ 指向所属类的prototype

实例去调用某个属性的时候

实例.xxxx

先在自己身上查找这个属性,没有的话,通过__proto__向上层对象A 查找,

上层对象A若也没有这个属性,则接着通过__proto__向A的上层对象B中查找,。。。。

一直找到基类(Object类)的原型(prototype),这时都没有对应的属性时,结果就是undefind

因为基类的prototype的 __proto__是null;也就是说基类的prototype是最顶层了;

以上通过__proto__向上查找属性的这个线路 称为原型链;

常见的内置类 或者 自己定义的类的原型 的 __proto__一般都是指向基类的原型

Array String Nubmer Boolean Function...

Student.prototype.__proto__ === Object.prototype

Object 基类

Array.prototype.__proto__ === Object.prototype

*/


constructor

[].constructor === Array;

({}).constructor === Object;

// constructor这个属性之所以能有用来判断数据类型

// 是因为实例调用constructor都是调用的原型上的constructor,指向就是构造函数本身

function isArray(option) {

return option.constructor === Array

}

// Array.isArray() es6新增的API

isArray([]) // true

isArray({}) // false


instanceof

/*

A instanceof B

从A到基类的原型,这条原型链上有没有B的原型存在;

特殊: 只能用于引用数据类型,值类型不适用;

*/

let ary = [];

var num = 1;

// console.log(num instanceof Number)

console.log(ary instanceof Number)

console.log(ary instanceof Array)

console.log(ary instanceof Object)


in

Array.prototype.myMap = function (cb) {

// myMap 的返回值是一个新数组 长度和this是一样的

// 新数组中的每一项都是由cb的返回结果决定的

let temp = [];

for (let i = 0; i < this.length; i++) {

let res = cb(this[i])

temp.push(res)

}

return temp

}

var ary = [111, 222, 333]

let res = ary.myMap(item=> {

// res 中的项 是由这个回调函数的返回结果决定的

return item

})

console.log(res)

</script>

<script src=''>

Array.prototype.myForEach = function (cb) {

// this --> ary

// cb 对应的是下方传递的回调函数

// 使用 for循环这个数组ary;然后执行回调cb

// 执行cb的时候 要把 数组中的项传给这个cb;

for (let i = 0; i < this.length; i++) {

cb(this[i])

}

}

var ary = [111, 2222, 3333]

ary.myForEach((item) => {

console.log(item)

})

</script>

<script src=''>

function Person(name, age) {

this.name = name;

this.age = age;

}

Person.prototype.eat = false;

let p1 = newPerson('张三', false);

console.log(p1)

for (let k in p1) {

// console.log(p1.hasOwnProperty(k))

if (p1.hasOwnProperty(k)) {

console.log('属性名:', k, ' 属性值:', p1[k])

}

}

Object.keys(p1) // 把p1中的私有属性名都存放到一个数组当中 然后返回

Object.keys(p1).forEach(k=> {

console.log(k)

})

// obj.hasPubProperty(key) 看看key 是不是obj的公有有属性

Object.prototype.hasPubProperty123 = function (key) {

// this ---> p1 ; key 是不是this的共有属性

// 首先得是我们能够调用的属性 ,并且 不是私有的,这时才是公有的

// in 在JS中的翻译 直白点就是在 A in B : B是否能够调用A属性

return (key in this) && !this.hasOwnProperty(key)

}

p1.hasPubProperty123('eat') // false

p1.hasOwnProperty('name') // true

// 自己实现一个mypush 用法等同 push

Array.prototype.mypush = function (...args) { //[3,4,5,6,7]

// this --> ary // arguments

args.forEach(k=> {

this[this.length] = k

})

return this.length

}

var ary = [1, 2]

ary.mypush(3, 4, 5, 6, 7)

</script>

<script scr=''>

function Fn(x) {

let y = 20;

this.total = x + y;

this.say = function () {

console.log(`${x} + ${y} = ${this.total}`);

};

}

let f1 = Fn(10);

let f2 = newFn(10);

let f3 = newFn(20);

console.log(f2.total);

console.log(f2.x);

console.log(f3.y);

console.log(f1 === f2);

console.log(f2 === f3);

f2.say();

console.log(f2.say === f3.say);

// console.log(f1.total);

console.log(window.total);

window.say();

</script>

<script>

function fun() {

this.a = 0;

this.b = function () {

alert(this.a);

}

}

// 原型重写,需要注意constructor的指向问题

fun.prototype = {

constructor:fun,

b:function () {

this.a = 20;

alert(this.a);

},

c:function () {

this.a = 30;

alert(this.a)

}

};

var my_fun = new fun(); //{a:0,b:f}

my_fun.b(); // this 是 my_fun;;this.a-->my_fun.a

my_fun.__proto__.b()

console.log(my_fun.constructor)

</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值