经典大厂面试题“JS的底层逻辑”(一)

194 阅读3分钟

模板方法设计模式

研究对象为以下代码

var  Tea = function (type){
            this.type = type
            console.log('您准备泡一杯'+this.type) 
        }
        // 对象 prototype 添加方法
        Tea.prototype.boilWater = function() {
            console.log('把水煮沸');
        }
        Tea.prototype.steepTeaBag = function() {
            console.log('用沸水浸泡茶叶');
        }
        Tea.prototype.pourInCup = function() {
            console.log('把茶水倒进杯子');
        }
        Tea.prototype.addLemon = function() {
            console.log('加入柠檬');
        }
        // 接口,模板方法接口,
        Tea.prototype.init = function(){
            this.boilWater()
            this.steepTeaBag()
            this.pourInCup()
            this.addLemon()
        }

        var lemonTea = new Tea('柠檬茶');
        lemonTea.init();

函数就是可执行的对象

在 JavaScript中函数就是对象。对象拥有一个连到原型对象的隐藏连接。对象字面量产生的对象连接到 object.prototype。函数对象连接到 Function. prototype。每个函数在创建时附有两个附加的隐藏属性:函数的上下文和实现函数行为的代码

1、js 变量类型是由值来决定的 2、js 除了简单数据类型,就是对象(函数就是可执行的对象) 3、其实JS里面没有类 早期没有提供class关键字

函数对象的介绍

通过函数字面量来创造函数对象:

//创建一个名为 Tea 的函数,即可执行的对象
var  Tea = function (type){
            this.type = type
            console.log('您准备泡一杯'+this.type) 
        }

函数字面量包括四个部分

第一个部分是保留字 functson. 一个可重复使用的代码块,即函数

第二个部分是函数名var,它可以被省略。函数可以用它的名字来递归地调用自己。它的名字也能被调试器和开发工具用来识别函数。 例如替换为function Tea (type)也是一样的效果

function Tea (type){
            this.type = type
            console.log('您准备泡一杯'+this.type) 
        }

第三个部分是包限在圆括号中的一组参数(type),其中每个參数用逗号分隔如(text,prompt)。这些名称将被定义为函数中的变量。它们不像普通的变量那样将被初始化为 undetined,而是在该函数被调用时初始化为实际提供的参数的值。

第四个部分是包限在花括号中的一组语句。这些语句是函数的主体。它们在函数被调用时执行

方法调用模式

Tea是可执行的对象,负责构建我们的对象,this指向的这些属性就是实例的属性模板

this.type = type

构造器调用模式

如果在一个函数前面带上new来调用,那么将创建一个隐藏连接到该函数的prototype成员的新对象,同时this将会被绑定到那个新对象上。Tea 和柠檬茶之间没有血缘关系,Tea是原型对象,lemonTea是构造对象

目的就是结合 new 前缀调用的函数被称为构造器函数。按照约定,它们保存在以大写格式命名的变量里(Tea)。

var lemonTea = new Tea('柠檬茶');

对象 prototype 添加方法

  • Tea通过prototype添加一些方法,都可以被以他为原型的对象共享(public)

对制作茶过程中的各个步骤进行的函数封装

        Tea.prototype.boilWater = function() {
            console.log('把水煮沸');
        }
        Tea.prototype.steepTeaBag = function() {
            console.log('用沸水浸泡茶叶');
        }
        Tea.prototype.pourInCup = function() {
            console.log('把茶水倒进杯子');
        }
        Tea.prototype.addLemon = function() {
            console.log('加入柠檬');
        }

设置模板方法接口

对函数封装了之后,便可设置个init接口直接调用

Tea.prototype.init = function(){
            this.boilWater()
            this.steepTeaBag()
            this.pourInCup()
            this.addLemon()
        }
         lemonTea.init();

302c2920e1c907ff0bb67b4652a8960.png

(番外篇——AI)

作为AI的原驻民,再来巩固一下AI知识,使用AI达到一样的效果

和我上一篇的流程一样(不熟悉的可以看看之前的文章)

  • 设置安全的环境变量
  • 配置openai环境
  • 设置机器人的角色、模型、回复的方式等
require('dotenv').config();

const OpenAI = require('openai');

const client = new OpenAI({
    apiKey: process.env.OPENAI_API_KEY,
    baseURL:'https://api.chatanywhere.tech/v1'
})
const getChatCompletion = async function (model,prompt) {
    const response = await client.chat.completions.create({
        model:model,
        n:2,//生成几个结果
        messages:[{role:'user',content:prompt}],
    })

    return response.choices[0].message.content
}
const chatCompletion = await getChatCompletion('gpt-3.5-turbo',prompt)
    console.log(chatCompletion)

设置清晰准确的Prompt

    const prompt = `
    您将获得由三个引号括起来的文本
    如果他包含一系列的指令,则需要按照以下的格式重新编写这些指令

    第一步 - 。。。
    第二步 - 。。。
    。。。
    第N步 - 。。。

    如果文本中不含一系列的指令,则直接写“未提供步骤”
    """${text}"""
    `

运行试试看

b323ce6c2701bd06007cfeba49c1bb5.png