1.获取原型对象
Object.getPrototypeOf
方法在 JavaScript 中用于获取指定对象的原型对象,即对象链中的下一个链接。原型对象是对象继承属性和方法的来源。这个方法对于理解对象的继承结构和访问对象原型上的属性和方法非常有用。
举例:
// 构造函数
function Animal(name) {
this.name = name;
}
// 添加一个方法到 Animal 原型上
Animal.prototype.speak = function() {
console.log(this.name + ' makes a sound.');
};
// 使用构造函数创建一个实例
const animal = new Animal('Generic animal');
// 获取 animal 实例的原型对象
const proto = Object.getPrototypeOf(animal);
// 由于 Animal.prototype 被设置为 animal 的原型,proto 将指向 Animal.prototype
console.log(proto === Animal.prototype); // 输出: true
// 调用通过原型继承的 speak 方法
proto.speak.call(animal); // 输出: Generic animal makes a sound.
// 创建另一个对象,使用 Object.create 方法设置其原型为 animal 实例
const anotherAnimal = Object.create(animal);
// 此时,anotherAnimal 的原型是 animal 实例
const anotherProto = Object.getPrototypeOf(anotherAnimal);
console.log(anotherProto === animal); // 输出: true
// 由于 anotherAnimal 是以 animal 为原型创建的,它不会继承 Animal.prototype 上的方法
anotherProto.speak.call(anotherAnimal); // 输出: undefined makes a sound.
在这个例子中,我们首先定义了一个 Animal
构造函数,并为其原型添加了一个 speak
方法。然后,我们使用 new
关键字创建了一个 animal
实例。
通过 Object.getPrototypeOf
方法,我们获取了 animal
实例的原型对象,它指向 Animal.prototype
。因此,当我们调用 proto.speak.call(animal)
时,它能够正确地输出 animal
实例的名字和它发出的声音。
接下来,我们使用 Object.create
方法创建了一个新的对象 anotherAnimal
,其原型被设置为 animal
实例。这意味着 anotherAnimal
继承自 animal
实例,而不是 Animal.prototype
。当我们尝试通过 anotherProto.speak.call(anotherAnimal)
调用 speak
方法时,由于 animal
实例上没有 speak
方法,所以输出为 undefined makes a sound.
。
这个例子展示了 Object.getPrototypeOf
方法如何帮助我们访问和理解对象的原型链,以及如何通过原型链访问对象的属性和方法。
2.设置原型对象
Object.setPrototypeOf
在 JavaScript 中用于设置一个对象的原型(即内部的 [[Prototype]]
属性)。这个方法通常用于改变对象的继承链,或者将一个对象的原型设置为 null
来防止进一步的原型继承。
举例:
// 构造函数
function Animal(name) {
this.name = name;
}
// 添加一个方法到 Animal 原型上
Animal.prototype.speak = function() {
console.log(this.name + ' makes a sound.');
};
// 使用构造函数创建一个实例
const animal = new Animal('Generic animal');
// 创建另一个构造函数
function Vehicle(make, model) {
this.make = make;
this.model = model;
}
// 添加一个方法到 Vehicle 原型上
Vehicle.prototype.describe = function() {
console.log('This is a ' + this.make + ' ' + this.model + ' vehicle.');
};
// 使用构造函数创建一个 Vehicle 实例
const car = new Vehicle('Toyota', 'Corolla');
// 现在,我们将 car 实例的原型设置为 animal 实例
// 这意味着 car 将继承 animal 实例的所有属性和方法
Object.setPrototypeOf(car, animal);
// 验证原型链是否已改变
console.log(Object.getPrototypeOf(car) === animal); // 输出: true
// 由于 car 的原型现在是 animal,它继承了 speak 方法
car.speak(); // 输出: Generic animal makes a sound.
// 为了演示,我们也可以将 car 的原型设置为 null,这样它就不再有原型
Object.setPrototypeOf(car, null);
// 再次验证原型链
console.log(Object.getPrototypeOf(car) === null); // 输出: true
// 现在 car 没有原型,因此不能访问 speak 方法
car.speak(); // 输出: TypeError: car.speak is not a function
在这个例子中,我们首先定义了两个构造函数 Animal
和 Vehicle
,并分别为它们的原型添加了方法 speak
和 describe
。然后,我们分别使用这两个构造函数创建了 animal
和 car
实例。
接下来,我们使用 Object.setPrototypeOf
方法将 car
实例的原型设置为 animal
实例。这意味着 car
现在继承了 animal
实例的所有属性和方法。我们通过调用 car.speak()
来验证这一点,它输出了 animal
实例的名字和声音。
最后,我们再次使用 Object.setPrototypeOf
方法将 car
的原型设置为 null
,这意味着 car
将不再继承任何属性和方法。当我们尝试调用 car.speak()
时,由于 car
没有 speak
方法,因此抛出了一个类型错误。
这个例子展示了 Object.setPrototypeOf
方法如何用于修改对象的原型链,以及如何通过改变原型来控制对象继承的属性和方法
3.获取所有当前对象属性
Object.getOwnPropertyNames
Object.getOwnPropertyNames
方法在 JavaScript 中用于获取一个对象的所有可枚举的自有属性的名称,包括那些不可枚举的属性。这个方法返回一个字符串数组,数组中的每个元素都是对象的一个属性名。
这个方法对于理解对象的内部属性非常有用,尤其是当你想要获取对象所有的属性,包括那些可能在常规枚举中被忽略的属性时。
举例:
// 定义一个对象
const myObject = {
enumerableProperty: 'I am enumerable',
nonEnumerableProperty: 'I am not enumerable'
};
// 添加一个不可枚举的属性
Object.defineProperty(myObject, 'anotherNonEnumerableProperty', {
value: 'Another non-enumerable property',
enumerable: false
});
// 使用 Object.keys 获取对象的键(只能获取可枚举的键)
const keys = Object.keys(myObject);
console.log(keys); // 输出: ["enumerableProperty"]
// 使用 Object.getOwnPropertyNames 获取对象的所有自有属性名称
const allPropertyNames = Object.getOwnPropertyNames(myObject);
console.log(allPropertyNames); // 输出: ["enumerableProperty", "nonEnumerableProperty", "anotherNonEnumerableProperty"]
在这个例子中,我们首先定义了一个对象 myObject
,它包含一个可枚举属性 enumerableProperty
和一个不可枚举属性 nonEnumerableProperty
。然后,我们使用 Object.defineProperty
方法添加了另一个不可枚举属性 anotherNonEnumerableProperty
。
当我们使用 Object.keys
方法时,它只返回了可枚举的属性 enumerableProperty
。然而,当我们使用 Object.getOwnPropertyNames
方法时,它返回了所有的自有属性名称,包括那些不可枚举的属性 nonEnumerableProperty
和 anotherNonEnumerableProperty
。
这个方法在调试或者当你需要分析一个对象的所有属性时非常有用,尤其是当你不确定对象中是否存在某些属性时。
4. 获取特殊属性
Object.getOwnPropertySymbols
在 JavaScript 中用于获取一个对象的所有自有符号属性(Symbol properties)。符号属性是一种特殊的属性,它通过 Symbol
函数创建,具有唯一性,即使两个不同的 Symbol
看起来可能相同,它们在技术上也是不同的。
这个方法对于处理那些希望避免属性名冲突的高级用例非常有用,因为 Symbol
值是唯一的,不会与其他属性名或 Symbol
值冲突。
// 创建一个对象
const myObject = {};
// 定义两个符号属性并添加到对象中
const sym1 = Symbol('uniqueDescription1');
const sym2 = Symbol('uniqueDescription2');
myObject[sym1] = 'This is a symbol property with description 1';
myObject[sym2] = 'This is another symbol property with description 2';
// 使用 Object.getOwnPropertyNames 获取对象的所有自有字符串属性名称
const stringPropertyNames = Object.getOwnPropertyNames(myObject);
console.log(stringPropertyNames); // 输出: []
// 使用 Object.getOwnPropertySymbols 获取对象的所有自有符号属性
const symbolProperties = Object.getOwnPropertySymbols(myObject);
console.log(symbolProperties); // 输出: [Symbol(uniqueDescription1), Symbol(uniqueDescription2)]
// 打印符号属性的描述和值
symbolProperties.forEach(sym => {
console.log(`Symbol description: ${sym.description}, Symbol value: ${myObject[sym]}`);
});
// 输出:
// Symbol description: uniqueDescription1, Symbol value: This is a symbol property with description 1
// Symbol description: uniqueDescription2, Symbol value: This is another symbol property with description 2
在这个例子中,我们首先创建了一个空对象 myObject
,然后定义了两个具有不同描述的符号,并使用这些符号作为属性名将它们添加到 myObject
中。我们还为这些符号属性赋予了字符串值。
当我们使用 Object.getOwnPropertyNames
方法时,它没有返回任何属性名称,因为 myObject
中没有可枚举的字符串属性。然而,当我们使用 Object.getOwnPropertySymbols
方法时,它返回了一个包含所有自有符号属性的数组。
最后,我们遍历了符号属性数组,并打印了每个符号的描述和对应的值。这展示了如何访问和使用符号属性,尽管在大多数情况下,我们更倾向于使用 Object.keys
或 Object.getOwnPropertyNames
来处理常规属性。
5.获取可枚举属性
Object.keys
Object.keys 方法在 JavaScript 中用于获取一个对象自身的所有可枚举属性的键名(属性名),并以数组的形式返回。这个方法通常用于遍历对象的属性,尤其是当你需要对对象的属性进行操作时。
// 创建一个对象,包含多个属性,其中一些属性是不可枚举的
const myObject = {
enumerableProperty: 'This property is enumerable',
nonEnumerableProperty: 'This property is not enumerable',
anotherEnumerableProperty: 'Another enumerable property'
};
// 使用 Object.defineProperty 为对象添加一个不可枚举的属性
Object.defineProperty(myObject, 'anotherNonEnumerableProperty', {
value: 'This is another non-enumerable property',
writable: true,
enumerable: false,
configurable: true
});
// 使用 Object.keys 获取对象的可枚举属性键名
const keys = Object.keys(myObject);
console.log(keys); // 输出: ["enumerableProperty", "anotherEnumerableProperty"]
// 尝试使用 for...in 循环遍历对象的所有属性
for (const key in myObject) {
console.log(key + ': ' + myObject[key]);
}
// 输出:
// enumerableProperty: This property is enumerable
// nonEnumerableProperty: This property is not enumerable
// anotherEnumerableProperty: Another enumerable property
// anotherNonEnumerableProperty: This is another non-enumerable property
// 说明:for...in 循环会枚举对象自身的属性以及其原型链上可枚举的属性
在这个例子中,我们首先创建了一个 myObject
对象,它包含一个可枚举属性 enumerableProperty
,一个不可枚举属性 nonEnumerableProperty
,以及一个通过 Object.defineProperty
添加的不可枚举属性 anotherNonEnumerableProperty
。
当我们使用 Object.keys
方法时,它只返回了可枚举的属性键名,即 enumerableProperty
和 anotherEnumerableProperty
。不可枚举的属性 nonEnumerableProperty
和 anotherNonEnumerableProperty
没有被包含在内。
随后,我们使用 for...in
循环遍历对象的所有属性,包括可枚举和不可枚举的属性。这是因为 for...in
循环不仅枚举对象自身的属性,还会枚举其原型链上可枚举的属性。
通过这个例子,我们可以看到 Object.keys
方法如何用于获取对象的可枚举属性键名,这对于编写只处理可枚举属性的代码非常有用。同时,我们也了解了 for...in
循环与 Object.keys
方法在枚举属性方面的差异。
6.冻结对象
Object.preventExtensions
Object.preventExtensions
方法在 JavaScript 中用于阻止一个对象被添加新的属性,即冻结对象。如果操作成功,该方法返回 true
;如果对象已经是不可扩展的,或者操作失败(例如,对象是密封的),则返回 false
。
这个方法对于确保对象的完整性和安全性非常有用,尤其是在你不希望对象的结构在运行时被改变的情况下。
// 创建一个对象
const myObject = {
property1: 42
};
// 检查对象是否可扩展
console.log(Object.isExtensible(myObject)); // 输出: true
// 阻止对象扩展新的属性
const success = Object.preventExtensions(myObject);
console.log(success); // 输出: true
// 尝试添加新的属性
myObject.property2 = 'Hello';
console.log(myObject.property2); // 输出: undefined
// 再次检查对象是否可扩展
console.log(Object.isExtensible(myObject)); // 输出: false
// 修改现有属性的值
myObject.property1 = 100;
console.log(myObject.property1); // 输出: 100
// 删除现有属性
delete myObject.property1; // 返回 true,表示删除成功
console.log(myObject.property1); // 输出: undefined
在这个例子中,我们首先创建了一个对象 myObject
并给它定义了一个属性 property1
。使用 Object.isExtensible
方法检查对象是否可扩展,此时输出为 true
,表示对象可以添加新属性。
接着,我们调用 Object.preventExtensions
方法来防止对象扩展新属性。尝试给对象添加一个新属性 property2
,但是操作失败,新属性没有被添加到对象中,且 property2
的值为 undefined
。
尽管我们阻止了对象扩展新属性,但是现有的属性仍然可以被修改或删除。我们修改了 property1
的值,并成功将其删除。
这个例子展示了 Object.preventExtensions
方法如何用于控制对象的结构,防止对象被意外地修改,同时保持对现有属性的灵活性。
7.js常见语法
>>>
>>
特殊函数调用方式
...
8.例子
福建资源平台
//npm install crypto-js
const CryptoJS = require('crypto-js')
function bbb(t) {
//"EB444973714E4A40876CE66BE45D5930"
//"B5A8904209931867"
var e = CryptoJS.enc.Utf8.parse("EB444973714E4A40876CE66BE45D5930")
, n = CryptoJS.enc.Utf8.parse("B5A8904209931867")
, a = CryptoJS.AES.decrypt(t, e, {
iv: n,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return a.toString(CryptoJS.enc.Utf8)
}
function s(t, e) {
return t.toString().toUpperCase() > e.toString().toUpperCase() ? 1 : t.toString().toUpperCase() == e.toString().toUpperCase() ? 0 : -1
}
function l(t) {
for (var e = Object.keys(t).sort(s), n = "", a = 0; a < e.length; a++)
if (void 0 !== t[e[a]])
if (t[e[a]] && t[e[a]]instanceof Object || t[e[a]]instanceof Array) {
var i = JSON.stringify(t[e[a]]);
n += e[a] + i
} else
n += e[a] + t[e[a]];
return n
}
function ddd(t) {
for (var e in t)
"" !== t[e] && void 0 !== t[e] || delete t[e];
var n = "B3978D054A72A7002063637CCDF6B2E5" + l(t);
return CryptoJS.MD5(n).toString().toLowerCase();
}
// var ttt = {
// "ts": 1714308237360,
// "pageNo": 1,
// "pageSize": 20,
// "total": 3677,
// "KIND": "GCJS",
// "GGTYPE": "1",
// "timeType": "6",
// "BeginTime": "2023-10-28 00:00:00",
// "EndTime": "2024-04-28 23:59:59",
// "createTime": []
// }
// console.log(ddd(ttt))
import requests
import json
import zlib
# pip install PyExecJS
import execjs
import time
import hashlib
import base64
import os
import json
current_time = int(time.time()*1000)
def get_js():
f = open("fjj.js", 'r',encoding='utf8')
line = f.readline()
htmlstr = ''
while line:
htmlstr = htmlstr+line
line = f.readline()
return htmlstr
def get_des_psswd(function_name,e):
js_str = get_js()
ctx = execjs.compile(js_str)
#这里hello为js文件里的函数,e为向hello这个函数里传递的参数
#这里我们的e这个形参主要用来传递歌曲的id,这样我们只需要向该函数传递不同的歌曲Id,即可返回不同的下载链接
return (ctx.call(function_name,e))
for page in range(1,4):
data = {
"pageNo": page,
"pageSize": 20,
"total": 3679,
"KIND": "GCJS",
"GGTYPE": "1",
"timeType": "6",
"BeginTime": "2023-10-28 00:00:00",
"EndTime": "2024-04-28 23:59:59",
"createTime": [],
"ts": current_time
}
data2 = {
"pageNo": page,
"pageSize": 20,
"total": 3679,
"AREACODE": "",
"M_PROJECT_TYPE": "",
"KIND": "GCJS",
"GGTYPE": "1",
"PROTYPE": "",
"timeType": "6",
"BeginTime": "2023-10-28 00:00:00",
"EndTime": "2024-04-28 23:59:59",
"createTime": [],
"ts": current_time
}
sign = get_des_psswd('ddd',data2)
print(sign)
headers = {
"Accept": "application/json, text/plain, */*",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Content-Type": "application/json;charset=UTF-8",
"Origin": "https://ggzyfw.fj.gov.cn",
"Pragma": "no-cache",
"Referer": "https://ggzyfw.fj.gov.cn/business/list/",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
"portal-sign": sign,
"sec-ch-ua": "\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\", \"Microsoft Edge\";v=\"120\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\""
}
print(headers)
url = "https://ggzyfw.fj.gov.cn/FwPortalApi/Trade/TradeInfo"
data2 = json.dumps(data2, separators=(',', ':'))
response = requests.post(url, headers=headers, data=data2).json()
print(response)
response_text = response['Data']
result = get_des_psswd('bbb',response_text)
print(result)